[
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Awesome Claude Skills\n\nThank you for your interest in contributing to the premier collection of Claude Skills! This guide will help you add new skills that benefit the entire Claude community.\n\n## Before You Start\n\n- Ensure your skill is based on a **real use case**, not a hypothetical scenario.\n- Search existing skills to avoid duplicates.\n- If possible, attribute the use case to the original person or source.\n\n## Skill Requirements\n\nAll skills must:\n\n1. **Solve a real problem** - Based on actual usage, not theoretical applications.\n2. **Be well-documented** - Include clear instructions, examples, and use cases.\n3. **Be accessible** - Written for non-technical users when possible.\n4. **Include examples** - Show practical, real-world usage.\n5. **Be tested** - Verify the skill works across Claude.ai, Claude Code, and/or API.\n6. **Be safe** - Confirm before destructive operations.\n7. **Be portable** - Work across Claude platforms when applicable.\n\n## Skill Structure\n\nCreate a new folder with your skill name (use lowercase and hyphens):\n\n```\nskill-name/\n└── SKILL.md\n```\n\n## SKILL.md Template\n\nUse this template for your skill:\n\n```markdown\n---\nname: skill-name\ndescription: One-sentence description of what this skill does and when to use it.\n---\n\n# Skill Name\n\nDetailed description of the skill and what it helps users accomplish.\n\n## When to Use This Skill\n\n- Bullet point use case 1\n- Bullet point use case 2\n- Bullet point use case 3\n\n## What This Skill Does\n\n1. **Capability 1**: Description\n2. **Capability 2**: Description\n3. **Capability 3**: Description\n\n## How to Use\n\n### Basic Usage\n\n```\nSimple example prompt\n```\n\n### Advanced Usage\n\n```\nMore complex example prompt with options\n```\n\n## Example\n\n**User**: \"Example prompt\"\n\n**Output**:\n```\nShow what the skill produces\n```\n\n**Inspired by:** [Attribution to original source, if applicable]\n\n## Tips\n\n- Tip 1\n- Tip 2\n- Tip 3\n\n## Common Use Cases\n\n- Use case 1\n- Use case 2\n- Use case 3\n```\n\n## Adding Your Skill to README\n\n1. Choose the appropriate category:\n   - Business & Marketing\n   - Communication & Writing\n   - Creative & Media\n   - Development\n   - Productivity & Organization\n\n2. Add your skill in alphabetical order within the category:\n\n```markdown\n- [Skill Name](./skill-name/) - One-sentence description. Inspired by [Person/Source].\n```\n\n3. Follow the existing format exactly - no emojis, consistent punctuation.\n\n## Pull Request Process\n\n1. Fork the repository\n2. Create a branch: `git checkout -b add-skill-name`\n3. Add your skill folder with SKILL.md\n4. Update README.md with your skill in the appropriate category\n5. Commit your changes: `git commit -m \"Add [Skill Name] skill\"`\n6. Push to your fork: `git push origin add-skill-name`\n7. Open a Pull Request\n\n## Pull Request Guidelines\n\nYour PR should:\n\n- **Title**: \"Add [Skill Name] skill\"\n- **Description**: Explain the real-world use case and include:\n  - What problem it solves\n  - Who uses this workflow\n  - Attribution/inspiration source\n  - Example of how it's used\n\n## Code of Conduct\n\n- Be respectful and constructive\n- Credit original sources and inspirations\n- Focus on practical, helpful skills\n- Write clear, accessible documentation\n- Test your skills before submitting\n\n## Questions?\n\nOpen an issue if you have questions about contributing or need help structuring your skill.\n\n## Attribution\n\nWhen adding a skill based on someone's workflow or use case, include proper attribution:\n\n```markdown\n**Inspired by:** [Person Name]'s workflow\n```\n\nor\n\n```markdown\n**Credit:** Based on [Company/Team]'s process\n```\n\nExamples:\n- **Inspired by:** Dan Shipper's meeting analysis workflow\n- **Inspired by:** Teresa Torres's content research process\n- **Credit:** Based on Notion's documentation workflow\n\n## Skill Categories\n\n### Business & Marketing\nSkills for lead generation, competitive research, branding, and business development.\n\n### Communication & Writing\nSkills for improving communication, analyzing conversations, and creating content.\n\n### Creative & Media\nSkills for working with images, videos, audio, and creative content.\n\n### Development\nSkills for software development, documentation, and technical workflows.\n\n### Productivity & Organization\nSkills for organizing files, managing tasks, and personal productivity.\n\n---\n\nThank you for contributing to Awesome Claude Skills!\n\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">Awesome Claude Skills</h1>\n\n<p align=\"center\">\n<a href=\"https://platform.composio.dev/?utm_source=Github&utm_medium=Youtube&utm_campaign=2025-11&utm_content=AwesomeSkills\">\n  <img width=\"1280\" height=\"640\" alt=\"Composio banner\" src=\"https://github.com/user-attachments/assets/e91255af-e4ba-4d71-b1a8-bd081e8a234a\">\n</a>\n\n\n</p>\n\n<p align=\"center\">\n  <a href=\"https://awesome.re\">\n    <img src=\"https://awesome.re/badge.svg\" alt=\"Awesome\" />\n  </a>\n  <a href=\"https://makeapullrequest.com\">\n    <img src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\" alt=\"PRs Welcome\" />\n  </a>\n  <a href=\"https://www.apache.org/licenses/LICENSE-2.0\">\n    <img src=\"https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat-square\" alt=\"License: Apache-2.0\" />\n  </a>\n</p>\n<div>\n<p align=\"center\">\n  <a href=\"https://twitter.com/composio\">\n    <img src=\"https://img.shields.io/badge/Follow on X-000000?style=for-the-badge&logo=x&logoColor=white\" alt=\"Follow on X\" />\n  </a>\n  <a href=\"https://www.linkedin.com/company/composiohq/\">\n    <img src=\"https://img.shields.io/badge/Follow on LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white\" alt=\"Follow on LinkedIn\" />\n  </a>\n  <a href=\"https://discord.com/invite/composio\">\n    <img src=\"https://img.shields.io/badge/Join our Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white\" alt=\"Join our Discord\" />\n  </a>\n  </p>\n</div>\n\nA curated list of practical Claude Skills for enhancing productivity across Claude.ai, Claude Code, and the Claude API.\n\n\n> **Want skills that do more than generate text?** Claude can send emails, create issues, post to Slack, and take actions across 1000+ apps. [See how →](./connect/)\n\n---\n\n## Quickstart: Connect Claude to 500+ Apps\n\nThe **connect-apps** plugin lets Claude perform real actions - send emails, create issues, post to Slack. It handles auth and connects to 500+ apps using Composio under the hood.\n\n### 1. Install the Plugin\n\n```bash\nclaude --plugin-dir ./connect-apps-plugin\n```\n\n### 2. Run Setup\n\n```\n/connect-apps:setup\n```\n\nPaste your API key when asked. (Get a free key at [platform.composio.dev](https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills))\n\n### 3. Restart & Try It\n\n```bash\nexit\nclaude\n```\n\n> **Want skills that do more than generate text?** Claude can send emails, create issues, post to Slack, and take actions across 1000+ apps. [See how →](./connect/)\n\nIf you receive the email, Claude is now connected to 500+ apps.\n\n**[See all supported apps →](https://composio.dev/toolkits)**\n\n---\n\n## Contents\n\n- [What Are Claude Skills?](#what-are-claude-skills)\n- [Skills](#skills)\n  - [Document Processing](#document-processing)\n  - [Development & Code Tools](#development--code-tools)\n  - [Data & Analysis](#data--analysis)\n  - [Business & Marketing](#business--marketing)\n  - [Communication & Writing](#communication--writing)\n  - [Creative & Media](#creative--media)\n  - [Productivity & Organization](#productivity--organization)\n  - [Collaboration & Project Management](#collaboration--project-management)\n  - [Security & Systems](#security--systems)\n  - [App Automation via Composio](#app-automation-via-composio)\n- [Getting Started](#getting-started)\n- [Creating Skills](#creating-skills)\n- [Contributing](#contributing)\n- [Resources](#resources)\n- [License](#license)\n\n## What Are Claude Skills?\n\nClaude Skills are customizable workflows that teach Claude how to perform specific tasks according to your unique requirements. Skills enable Claude to execute tasks in a repeatable, standardized manner across all Claude platforms.\n\n## Skills\n\n### Document Processing\n\n- [docx](https://github.com/anthropics/skills/tree/main/skills/docx) - Create, edit, analyze Word docs with tracked changes, comments, formatting.\n- [pdf](https://github.com/anthropics/skills/tree/main/skills/pdf) - Extract text, tables, metadata, merge & annotate PDFs.\n- [pptx](https://github.com/anthropics/skills/tree/main/skills/pptx) - Read, generate, and adjust slides, layouts, templates.\n- [xlsx](https://github.com/anthropics/skills/tree/main/skills/xlsx) - Spreadsheet manipulation: formulas, charts, data transformations.\n- [Markdown to EPUB Converter](https://github.com/smerchek/claude-epub-skill) - Converts markdown documents and chat summaries into professional EPUB ebook files. *By [@smerchek](https://github.com/smerchek)*\n\n### Development & Code Tools\n\n- [artifacts-builder](https://github.com/anthropics/skills/tree/main/skills/web-artifacts-builder) - Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui).\n- [aws-skills](https://github.com/zxkane/aws-skills) - AWS development with CDK best practices, cost optimization MCP servers, and serverless/event-driven architecture patterns.\n- [Changelog Generator](./changelog-generator/) - Automatically creates user-facing changelogs from git commits by analyzing history and transforming technical commits into customer-friendly release notes.\n- [Claude Code Terminal Title](https://github.com/bluzername/claude-code-terminal-title) - Gives each Claud-Code terminal window a dynamic title that describes the work being done so you don't lose track of what window is doing what.\n- [D3.js Visualization](https://github.com/chrisvoncsefalvay/claude-d3js-skill) - Teaches Claude to produce D3 charts and interactive data visualizations. *By [@chrisvoncsefalvay](https://github.com/chrisvoncsefalvay)*\n- [FFUF Web Fuzzing](https://github.com/jthack/ffuf_claude_skill) - Integrates the ffuf web fuzzer so Claude can run fuzzing tasks and analyze results for vulnerabilities. *By [@jthack](https://github.com/jthack)*\n- [finishing-a-development-branch](https://github.com/obra/superpowers/tree/main/skills/finishing-a-development-branch) - Guides completion of development work by presenting clear options and handling chosen workflow.\n- [iOS Simulator](https://github.com/conorluddy/ios-simulator-skill) - Enables Claude to interact with iOS Simulator for testing and debugging iOS applications. *By [@conorluddy](https://github.com/conorluddy)*\n- [jules](https://github.com/sanjay3290/ai-skills/tree/main/skills/jules) - Delegate coding tasks to Google Jules AI agent for async bug fixes, documentation, tests, and feature implementation on GitHub repos. *By [@sanjay3290](https://github.com/sanjay3290)*\n- [LangSmith Fetch](./langsmith-fetch/) - Debug LangChain and LangGraph agents by automatically fetching and analyzing execution traces from LangSmith Studio. First AI observability skill for Claude Code. *By [@OthmanAdi](https://github.com/OthmanAdi)*\n- [MCP Builder](./mcp-builder/) - Guides creation of high-quality MCP (Model Context Protocol) servers for integrating external APIs and services with LLMs using Python or TypeScript.\n- [move-code-quality-skill](https://github.com/1NickPappas/move-code-quality-skill) - Analyzes Move language packages against the official Move Book Code Quality Checklist for Move 2024 Edition compliance and best practices.\n- [Playwright Browser Automation](https://github.com/lackeyjb/playwright-skill) - Model-invoked Playwright automation for testing and validating web applications. *By [@lackeyjb](https://github.com/lackeyjb)*\n- [prompt-engineering](https://github.com/NeoLabHQ/context-engineering-kit/tree/master/plugins/customaize-agent/skills/prompt-engineering) - Teaches well-known prompt engineering techniques and patterns, including Anthropic best practices and agent persuasion principles.\n- [pypict-claude-skill](https://github.com/omkamal/pypict-claude-skill) - Design comprehensive test cases using PICT (Pairwise Independent Combinatorial Testing) for requirements or code, generating optimized test suites with pairwise coverage.\n- [reddit-fetch](https://github.com/ykdojo/claude-code-tips/tree/main/skills/reddit-fetch) - Fetches Reddit content via Gemini CLI when WebFetch is blocked or returns 403 errors.\n- [Skill Creator](./skill-creator/) - Provides guidance for creating effective Claude Skills that extend capabilities with specialized knowledge, workflows, and tool integrations.\n- [Skill Seekers](https://github.com/yusufkaraaslan/Skill_Seekers) - Automatically converts any documentation website into a Claude AI skill in minutes. *By [@yusufkaraaslan](https://github.com/yusufkaraaslan)*\n- [software-architecture](https://github.com/NeoLabHQ/context-engineering-kit/tree/master/plugins/ddd/skills/software-architecture) - Implements design patterns including Clean Architecture, SOLID principles, and comprehensive software design best practices.\n- [subagent-driven-development](https://github.com/NeoLabHQ/context-engineering-kit/tree/master/plugins/sadd/skills/subagent-driven-development) - Dispatches independent subagents for individual tasks with code review checkpoints between iterations for rapid, controlled development.\n- [test-driven-development](https://github.com/obra/superpowers/tree/main/skills/test-driven-development) - Use when implementing any feature or bugfix, before writing implementation code.\n- [using-git-worktrees](https://github.com/obra/superpowers/blob/main/skills/using-git-worktrees/) - Creates isolated git worktrees with smart directory selection and safety verification.\n- [Connect](./connect/) - Connect Claude to any app. Send emails, create issues, post messages, update databases - take real actions across Gmail, Slack, GitHub, Notion, and 1000+ services.\n- [Webapp Testing](./webapp-testing/) - Tests local web applications using Playwright for verifying frontend functionality, debugging UI behavior, and capturing screenshots.\n\n### Data & Analysis\n\n- [CSV Data Summarizer](https://github.com/coffeefuelbump/csv-data-summarizer-claude-skill) - Automatically analyzes CSV files and generates comprehensive insights with visualizations without requiring user prompts. *By [@coffeefuelbump](https://github.com/coffeefuelbump)*\n- [deep-research](https://github.com/sanjay3290/ai-skills/tree/main/skills/deep-research) - Execute autonomous multi-step research using Gemini Deep Research Agent for market analysis, competitive landscaping, and literature reviews. *By [@sanjay3290](https://github.com/sanjay3290)*\n- [postgres](https://github.com/sanjay3290/ai-skills/tree/main/skills/postgres) - Execute safe read-only SQL queries against PostgreSQL databases with multi-connection support and defense-in-depth security. *By [@sanjay3290](https://github.com/sanjay3290)*\n- [root-cause-tracing](https://github.com/obra/superpowers/tree/main/skills/root-cause-tracing) - Use when errors occur deep in execution and you need to trace back to find the original trigger.\n\n### Business & Marketing\n\n- [Brand Guidelines](./brand-guidelines/) - Applies Anthropic's official brand colors and typography to artifacts for consistent visual identity and professional design standards.\n- [Competitive Ads Extractor](./competitive-ads-extractor/) - Extracts and analyzes competitors' ads from ad libraries to understand messaging and creative approaches that resonate.\n- [Domain Name Brainstormer](./domain-name-brainstormer/) - Generates creative domain name ideas and checks availability across multiple TLDs including .com, .io, .dev, and .ai extensions.\n- [Internal Comms](./internal-comms/) - Helps write internal communications including 3P updates, company newsletters, FAQs, status reports, and project updates using company-specific formats.\n- [Lead Research Assistant](./lead-research-assistant/) - Identifies and qualifies high-quality leads by analyzing your product, searching for target companies, and providing actionable outreach strategies.\n\n### Communication & Writing\n\n- [article-extractor](https://github.com/michalparkola/tapestry-skills-for-claude-code/tree/main/article-extractor) - Extract full article text and metadata from web pages.\n- [brainstorming](https://github.com/obra/superpowers/tree/main/skills/brainstorming) - Transform rough ideas into fully-formed designs through structured questioning and alternative exploration.\n- [Content Research Writer](./content-research-writer/) - Assists in writing high-quality content by conducting research, adding citations, improving hooks, and providing section-by-section feedback.\n- [family-history-research](https://github.com/emaynard/claude-family-history-research-skill) - Provides assistance with planning family history and genealogy research projects.\n- [Meeting Insights Analyzer](./meeting-insights-analyzer/) - Analyzes meeting transcripts to uncover behavioral patterns including conflict avoidance, speaking ratios, filler words, and leadership style.\n- [NotebookLM Integration](https://github.com/PleasePrompto/notebooklm-skill) - Lets Claude Code chat directly with NotebookLM for source-grounded answers based exclusively on uploaded documents. *By [@PleasePrompto](https://github.com/PleasePrompto)*\n- [Twitter Algorithm Optimizer](./twitter-algorithm-optimizer/) - Analyze and optimize tweets for maximum reach using Twitter's open-source algorithm insights. Rewrite and edit tweets to improve engagement and visibility.\n\n### Creative & Media\n\n- [Canvas Design](./canvas-design/) - Creates beautiful visual art in PNG and PDF documents using design philosophy and aesthetic principles for posters, designs, and static pieces.\n- [imagen](https://github.com/sanjay3290/ai-skills/tree/main/skills/imagen) - Generate images using Google Gemini's image generation API for UI mockups, icons, illustrations, and visual assets. *By [@sanjay3290](https://github.com/sanjay3290)*\n- [Image Enhancer](./image-enhancer/) - Improves image and screenshot quality by enhancing resolution, sharpness, and clarity for professional presentations and documentation.\n- [Slack GIF Creator](./slack-gif-creator/) - Creates animated GIFs optimized for Slack with validators for size constraints and composable animation primitives.\n- [Theme Factory](./theme-factory/) - Applies professional font and color themes to artifacts including slides, docs, reports, and HTML landing pages with 10 pre-set themes.\n- [Video Downloader](./video-downloader/) - Downloads videos from YouTube and other platforms for offline viewing, editing, or archival with support for various formats and quality options.\n- [youtube-transcript](https://github.com/michalparkola/tapestry-skills-for-claude-code/tree/main/youtube-transcript) - Fetch transcripts from YouTube videos and prepare summaries.\n\n### Productivity & Organization\n\n- [File Organizer](./file-organizer/) - Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures.\n- [Invoice Organizer](./invoice-organizer/) - Automatically organizes invoices and receipts for tax preparation by reading files, extracting information, and renaming consistently.\n- [kaizen](https://github.com/NeoLabHQ/context-engineering-kit/tree/master/plugins/kaizen/skills/kaizen) - Applies continuous improvement methodology with multiple analytical approaches, based on Japanese Kaizen philosophy and Lean methodology.\n- [n8n-skills](https://github.com/haunchen/n8n-skills) - Enables AI assistants to directly understand and operate n8n workflows.\n- [Raffle Winner Picker](./raffle-winner-picker/) - Randomly selects winners from lists, spreadsheets, or Google Sheets for giveaways and contests with cryptographically secure randomness.\n- [Tailored Resume Generator](./tailored-resume-generator/) - Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances.\n- [ship-learn-next](https://github.com/michalparkola/tapestry-skills-for-claude-code/tree/main/ship-learn-next) - Skill to help iterate on what to build or learn next, based on feedback loops.\n- [tapestry](https://github.com/michalparkola/tapestry-skills-for-claude-code/tree/main/tapestry) - Interlink and summarize related documents into knowledge networks.\n\n### Collaboration & Project Management\n\n- [git-pushing](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/engineering-workflow-plugin/skills/git-pushing) - Automate git operations and repository interactions.\n- [google-workspace-skills](https://github.com/sanjay3290/ai-skills/tree/main/skills) - Suite of Google Workspace integrations: Gmail, Calendar, Chat, Docs, Sheets, Slides, and Drive with cross-platform OAuth. *By [@sanjay3290](https://github.com/sanjay3290)*\n- [outline](https://github.com/sanjay3290/ai-skills/tree/main/skills/outline) - Search, read, create, and manage documents in Outline wiki instances (cloud or self-hosted). *By [@sanjay3290](https://github.com/sanjay3290)*\n- [review-implementing](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/engineering-workflow-plugin/skills/review-implementing) - Evaluate code implementation plans and align with specs.\n- [test-fixing](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/engineering-workflow-plugin/skills/test-fixing) - Detect failing tests and propose patches or fixes.\n\n### Security & Systems\n\n- [computer-forensics](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/computer-forensics-skills/skills/computer-forensics) - Digital forensics analysis and investigation techniques.\n- [file-deletion](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/computer-forensics-skills/skills/file-deletion) - Secure file deletion and data sanitization methods.\n- [metadata-extraction](https://github.com/mhattingpete/claude-skills-marketplace/tree/main/computer-forensics-skills/skills/metadata-extraction) - Extract and analyze file metadata for forensic purposes.\n- [threat-hunting-with-sigma-rules](https://github.com/jthack/threat-hunting-with-sigma-rules-skill) - Use Sigma detection rules to hunt for threats and analyze security events.\n\n### App Automation via Composio\n\nPre-built workflow skills for 78 SaaS apps via [Rube MCP (Composio)](https://composio.dev). Each skill includes tool sequences, parameter guidance, known pitfalls, and quick reference tables — all using real tool slugs discovered from Composio's API.\n\n**CRM & Sales**\n- [Close Automation](./close-automation/) - Automate Close CRM: leads, contacts, opportunities, activities, and pipelines.\n- [HubSpot Automation](./hubspot-automation/) - Automate HubSpot CRM: contacts, deals, companies, tickets, and email engagement.\n- [Pipedrive Automation](./pipedrive-automation/) - Automate Pipedrive: deals, contacts, organizations, activities, and pipelines.\n- [Salesforce Automation](./salesforce-automation/) - Automate Salesforce: objects, records, SOQL queries, and bulk operations.\n- [Zoho CRM Automation](./zoho-crm-automation/) - Automate Zoho CRM: leads, contacts, deals, accounts, and modules.\n\n**Project Management**\n- [Asana Automation](./asana-automation/) - Automate Asana: tasks, projects, sections, assignments, and workspaces.\n- [Basecamp Automation](./basecamp-automation/) - Automate Basecamp: to-do lists, messages, people, groups, and projects.\n- [ClickUp Automation](./clickup-automation/) - Automate ClickUp: tasks, lists, spaces, goals, and time tracking.\n- [Jira Automation](./jira-automation/) - Automate Jira: issues, projects, boards, sprints, and JQL queries.\n- [Linear Automation](./linear-automation/) - Automate Linear: issues, projects, cycles, teams, and workflows.\n- [Monday Automation](./monday-automation/) - Automate Monday.com: boards, items, columns, groups, and workspaces.\n- [Notion Automation](./notion-automation/) - Automate Notion: pages, databases, blocks, comments, and search.\n- [Todoist Automation](./todoist-automation/) - Automate Todoist: tasks, projects, sections, labels, and filters.\n- [Trello Automation](./trello-automation/) - Automate Trello: boards, cards, lists, members, and checklists.\n- [Wrike Automation](./wrike-automation/) - Automate Wrike: tasks, folders, projects, comments, and workflows.\n\n**Communication**\n- [Discord Automation](./discord-automation/) - Automate Discord: messages, channels, servers, roles, and reactions.\n- [Intercom Automation](./intercom-automation/) - Automate Intercom: conversations, contacts, companies, tickets, and articles.\n- [Microsoft Teams Automation](./microsoft-teams-automation/) - Automate Teams: messages, channels, teams, chats, and meetings.\n- [Slack Automation](./slack-automation/) - Automate Slack: messages, channels, search, reactions, threads, and scheduling.\n- [Telegram Automation](./telegram-automation/) - Automate Telegram: messages, chats, media, groups, and bots.\n- [WhatsApp Automation](./whatsapp-automation/) - Automate WhatsApp: messages, media, templates, groups, and business profiles.\n\n**Email**\n- [Gmail Automation](./gmail-automation/) - Automate Gmail: send/reply, search, labels, drafts, and attachments.\n- [Outlook Automation](./outlook-automation/) - Automate Outlook: emails, folders, contacts, and calendar integration.\n- [Postmark Automation](./postmark-automation/) - Automate Postmark: transactional emails, templates, servers, and delivery stats.\n- [SendGrid Automation](./sendgrid-automation/) - Automate SendGrid: emails, templates, contacts, lists, and campaign stats.\n\n**Code & DevOps**\n- [Bitbucket Automation](./bitbucket-automation/) - Automate Bitbucket: repos, PRs, branches, issues, and workspaces.\n- [CircleCI Automation](./circleci-automation/) - Automate CircleCI: pipelines, workflows, jobs, and project configuration.\n- [Datadog Automation](./datadog-automation/) - Automate Datadog: monitors, dashboards, metrics, incidents, and alerts.\n- [GitHub Automation](./github-automation/) - Automate GitHub: issues, PRs, repos, branches, actions, and code search.\n- [GitLab Automation](./gitlab-automation/) - Automate GitLab: issues, MRs, projects, pipelines, and branches.\n- [PagerDuty Automation](./pagerduty-automation/) - Automate PagerDuty: incidents, services, schedules, escalation policies, and on-call.\n- [Render Automation](./render-automation/) - Automate Render: services, deploys, and project management.\n- [Sentry Automation](./sentry-automation/) - Automate Sentry: issues, events, projects, releases, and alerts.\n- [Supabase Automation](./supabase-automation/) - Automate Supabase: SQL queries, table schemas, edge functions, and storage.\n- [Vercel Automation](./vercel-automation/) - Automate Vercel: deployments, projects, domains, environment variables, and logs.\n\n**Storage & Files**\n- [Box Automation](./box-automation/) - Automate Box: files, folders, search, sharing, collaborations, and sign requests.\n- [Dropbox Automation](./dropbox-automation/) - Automate Dropbox: files, folders, search, sharing, and batch operations.\n- [Google Drive Automation](./google-drive-automation/) - Automate Google Drive: upload, download, search, share, and organize files.\n- [OneDrive Automation](./one-drive-automation/) - Automate OneDrive: files, folders, search, sharing, permissions, and versioning.\n\n**Spreadsheets & Databases**\n- [Airtable Automation](./airtable-automation/) - Automate Airtable: records, tables, bases, views, and field management.\n- [Coda Automation](./coda-automation/) - Automate Coda: docs, tables, rows, formulas, and automations.\n- [Google Sheets Automation](./googlesheets-automation/) - Automate Google Sheets: read/write cells, formatting, formulas, and batch operations.\n\n**Calendar & Scheduling**\n- [Cal.com Automation](./cal-com-automation/) - Automate Cal.com: event types, bookings, availability, and scheduling.\n- [Calendly Automation](./calendly-automation/) - Automate Calendly: events, invitees, event types, scheduling links, and availability.\n- [Google Calendar Automation](./google-calendar-automation/) - Automate Google Calendar: events, attendees, free/busy, and recurring schedules.\n- [Outlook Calendar Automation](./outlook-calendar-automation/) - Automate Outlook Calendar: events, attendees, reminders, and recurring schedules.\n\n**Social Media**\n- [Instagram Automation](./instagram-automation/) - Automate Instagram: posts, stories, comments, media, and business insights.\n- [LinkedIn Automation](./linkedin-automation/) - Automate LinkedIn: posts, profiles, companies, images, and comments.\n- [Reddit Automation](./reddit-automation/) - Automate Reddit: posts, comments, subreddits, voting, and moderation.\n- [TikTok Automation](./tiktok-automation/) - Automate TikTok: video uploads, queries, and creator management.\n- [Twitter Automation](./twitter-automation/) - Automate Twitter/X: tweets, search, users, lists, and engagement.\n- [YouTube Automation](./youtube-automation/) - Automate YouTube: videos, channels, playlists, comments, and subscriptions.\n\n**Marketing & Email Marketing**\n- [ActiveCampaign Automation](./activecampaign-automation/) - Automate ActiveCampaign: contacts, deals, campaigns, lists, and automations.\n- [Brevo Automation](./brevo-automation/) - Automate Brevo: contacts, email campaigns, transactional emails, and lists.\n- [ConvertKit Automation](./convertkit-automation/) - Automate ConvertKit (Kit): subscribers, tags, sequences, broadcasts, and forms.\n- [Klaviyo Automation](./klaviyo-automation/) - Automate Klaviyo: profiles, lists, segments, campaigns, and events.\n- [Mailchimp Automation](./mailchimp-automation/) - Automate Mailchimp: audiences, campaigns, templates, segments, and reports.\n\n**Support & Helpdesk**\n- [Freshdesk Automation](./freshdesk-automation/) - Automate Freshdesk: tickets, contacts, agents, groups, and canned responses.\n- [Freshservice Automation](./freshservice-automation/) - Automate Freshservice: tickets, assets, changes, problems, and service catalog.\n- [Help Scout Automation](./helpdesk-automation/) - Automate Help Scout: conversations, customers, mailboxes, and tags.\n- [Zendesk Automation](./zendesk-automation/) - Automate Zendesk: tickets, users, organizations, search, and macros.\n\n**E-commerce & Payments**\n- [Shopify Automation](./shopify-automation/) - Automate Shopify: products, orders, customers, inventory, and GraphQL queries.\n- [Square Automation](./square-automation/) - Automate Square: payments, customers, catalog, orders, and locations.\n- [Stripe Automation](./stripe-automation/) - Automate Stripe: charges, customers, products, subscriptions, and refunds.\n\n**Design & Collaboration**\n- [Canva Automation](./canva-automation/) - Automate Canva: designs, templates, assets, folders, and brand kits.\n- [Confluence Automation](./confluence-automation/) - Automate Confluence: pages, spaces, search, CQL, labels, and versions.\n- [DocuSign Automation](./docusign-automation/) - Automate DocuSign: envelopes, templates, signing, and document management.\n- [Figma Automation](./figma-automation/) - Automate Figma: files, components, comments, projects, and team management.\n- [Miro Automation](./miro-automation/) - Automate Miro: boards, sticky notes, shapes, connectors, and items.\n- [Webflow Automation](./webflow-automation/) - Automate Webflow: CMS collections, items, sites, publishing, and assets.\n\n**Analytics & Data**\n- [Amplitude Automation](./amplitude-automation/) - Automate Amplitude: events, cohorts, user properties, and analytics queries.\n- [Google Analytics Automation](./google-analytics-automation/) - Automate Google Analytics: reports, dimensions, metrics, and property management.\n- [Mixpanel Automation](./mixpanel-automation/) - Automate Mixpanel: events, funnels, cohorts, annotations, and JQL queries.\n- [PostHog Automation](./posthog-automation/) - Automate PostHog: events, persons, feature flags, insights, and annotations.\n- [Segment Automation](./segment-automation/) - Automate Segment: sources, destinations, tracking, and warehouse connections.\n\n**HR & People**\n- [BambooHR Automation](./bamboohr-automation/) - Automate BambooHR: employees, time off, reports, and directory management.\n\n**Automation Platforms**\n- [Make Automation](./make-automation/) - Automate Make (Integromat): scenarios, connections, and execution management.\n\n**Zoom & Meetings**\n- [Zoom Automation](./zoom-automation/) - Automate Zoom: meetings, recordings, participants, webinars, and reports.\n\n## Getting Started\n\n### Using Skills in Claude.ai\n\n1. Click the skill icon (🧩) in your chat interface.\n2. Add skills from the marketplace or upload custom skills.\n3. Claude automatically activates relevant skills based on your task.\n\n### Using Skills in Claude Code\n\n1. Place the skill in `~/.config/claude-code/skills/`:\n   ```bash\n   mkdir -p ~/.config/claude-code/skills/\n   cp -r skill-name ~/.config/claude-code/skills/\n   ```\n\n2. Verify skill metadata:\n   ```bash\n   head ~/.config/claude-code/skills/skill-name/SKILL.md\n   ```\n\n3. Start Claude Code:\n   ```bash\n   claude\n   ```\n\n4. The skill loads automatically and activates when relevant.\n\n### Using Skills via API\n\nUse the Claude Skills API to programmatically load and manage skills:\n\n```python\nimport anthropic\n\nclient = anthropic.Anthropic(api_key=\"your-api-key\")\n\nresponse = client.messages.create(\n    model=\"claude-3-5-sonnet-20241022\",\n    skills=[\"skill-id-here\"],\n    messages=[{\"role\": \"user\", \"content\": \"Your prompt\"}]\n)\n```\n\nSee the [Skills API documentation](https://docs.claude.com/en/api/skills-guide) for details.\n\n## Creating Skills\n\n### Skill Structure\n\nEach skill is a folder containing a `SKILL.md` file with YAML frontmatter:\n\n```\nskill-name/\n├── SKILL.md          # Required: Skill instructions and metadata\n├── scripts/          # Optional: Helper scripts\n├── templates/        # Optional: Document templates\n└── resources/        # Optional: Reference files\n```\n\n### Basic Skill Template\n\n```markdown\n---\nname: my-skill-name\ndescription: A clear description of what this skill does and when to use it.\n---\n\n# My Skill Name\n\nDetailed description of the skill's purpose and capabilities.\n\n## When to Use This Skill\n\n- Use case 1\n- Use case 2\n- Use case 3\n\n## Instructions\n\n[Detailed instructions for Claude on how to execute this skill]\n\n## Examples\n\n[Real-world examples showing the skill in action]\n```\n\n### Skill Best Practices\n\n- Focus on specific, repeatable tasks\n- Include clear examples and edge cases\n- Write instructions for Claude, not end users\n- Test across Claude.ai, Claude Code, and API\n- Document prerequisites and dependencies\n- Include error handling guidance\n\n## Contributing\n\nWe welcome contributions! Please read our [Contributing Guidelines](CONTRIBUTING.md) for details on:\n\n- How to submit new skills\n- Skill quality standards\n- Pull request process\n- Code of conduct\n\n### Quick Contribution Steps\n\n1. Ensure your skill is based on a real use case\n2. Check for duplicates in existing skills\n3. Follow the skill structure template\n4. Test your skill across platforms\n5. Submit a pull request with clear documentation\n\n## Resources\n\n### Official Documentation\n\n- [Claude Skills Overview](https://www.anthropic.com/news/skills) - Official announcement and features\n- [Skills User Guide](https://support.claude.com/en/articles/12512180-using-skills-in-claude) - How to use skills in Claude\n- [Creating Custom Skills](https://support.claude.com/en/articles/12512198-creating-custom-skills) - Skill development guide\n- [Skills API Documentation](https://docs.claude.com/en/api/skills-guide) - API integration guide\n- [Agent Skills Blog Post](https://anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills) - Engineering deep dive\n\n### Community Resources\n\n- [Anthropic Skills Repository](https://github.com/anthropics/skills) - Official example skills\n- [Claude Community](https://community.anthropic.com) - Discuss skills with other users\n- [Skills Marketplace](https://claude.ai/marketplace) - Discover and share skills\n\n### Inspiration & Use Cases\n\n- [Lenny's Newsletter](https://www.lennysnewsletter.com/p/everyone-should-be-using-claude-code) - 50 ways people use Claude Code\n- [Notion Skills](https://www.notion.so/notiondevs/Notion-Skills-for-Claude-28da4445d27180c7af1df7d8615723d0) - Notion integration skills\n\n\n## Join the Community\n\n- [Join our Discord](https://discord.com/invite/composio) - Chat with other developers building Claude Skills\n- [Follow on Twitter/X](https://x.com/composio) - Stay updated on new skills and features\n- Questions? [support@composio.dev](mailto:support@composio.dev)\n\n---\n\n<p align=\"center\">\n  <b>Join 20,000+ developers building agents that ship</b>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills\">\n    <img src=\"https://img.shields.io/badge/Get_Started_Free-4F46E5?style=for-the-badge\" alt=\"Get Started\"/>\n  </a>\n</p>\n\n## License\n\nThis repository is licensed under the Apache License 2.0.\n\nIndividual skills may have different licenses - please check each skill's folder for specific licensing information.\n\n---\n\n**Note**: Claude Skills work across Claude.ai, Claude Code, and the Claude API. Once you create a skill, it's portable across all platforms, making your workflows consistent everywhere you use Claude.\n\n- [AgentsKB](https://agentskb.com) - Upgrade your AI with researched answers. We did the research so your AI gets it right the first time.\n"
  },
  {
    "path": "artifacts-builder/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "artifacts-builder/SKILL.md",
    "content": "---\nname: artifacts-builder\ndescription: Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Artifacts Builder\n\nTo build powerful frontend claude.ai artifacts, follow these steps:\n1. Initialize the frontend repo using `scripts/init-artifact.sh`\n2. Develop your artifact by editing the generated code\n3. Bundle all code into a single HTML file using `scripts/bundle-artifact.sh`\n4. Display artifact to user\n5. (Optional) Test the artifact\n\n**Stack**: React 18 + TypeScript + Vite + Parcel (bundling) + Tailwind CSS + shadcn/ui\n\n## Design & Style Guidelines\n\nVERY IMPORTANT: To avoid what is often referred to as \"AI slop\", avoid using excessive centered layouts, purple gradients, uniform rounded corners, and Inter font.\n\n## Quick Start\n\n### Step 1: Initialize Project\n\nRun the initialization script to create a new React project:\n```bash\nbash scripts/init-artifact.sh <project-name>\ncd <project-name>\n```\n\nThis creates a fully configured project with:\n- ✅ React + TypeScript (via Vite)\n- ✅ Tailwind CSS 3.4.1 with shadcn/ui theming system\n- ✅ Path aliases (`@/`) configured\n- ✅ 40+ shadcn/ui components pre-installed\n- ✅ All Radix UI dependencies included\n- ✅ Parcel configured for bundling (via .parcelrc)\n- ✅ Node 18+ compatibility (auto-detects and pins Vite version)\n\n### Step 2: Develop Your Artifact\n\nTo build the artifact, edit the generated files. See **Common Development Tasks** below for guidance.\n\n### Step 3: Bundle to Single HTML File\n\nTo bundle the React app into a single HTML artifact:\n```bash\nbash scripts/bundle-artifact.sh\n```\n\nThis creates `bundle.html` - a self-contained artifact with all JavaScript, CSS, and dependencies inlined. This file can be directly shared in Claude conversations as an artifact.\n\n**Requirements**: Your project must have an `index.html` in the root directory.\n\n**What the script does**:\n- Installs bundling dependencies (parcel, @parcel/config-default, parcel-resolver-tspaths, html-inline)\n- Creates `.parcelrc` config with path alias support\n- Builds with Parcel (no source maps)\n- Inlines all assets into single HTML using html-inline\n\n### Step 4: Share Artifact with User\n\nFinally, share the bundled HTML file in conversation with the user so they can view it as an artifact.\n\n### Step 5: Testing/Visualizing the Artifact (Optional)\n\nNote: This is a completely optional step. Only perform if necessary or requested.\n\nTo test/visualize the artifact, use available tools (including other Skills or built-in tools like Playwright or Puppeteer). In general, avoid testing the artifact upfront as it adds latency between the request and when the finished artifact can be seen. Test later, after presenting the artifact, if requested or if issues arise.\n\n## Reference\n\n- **shadcn/ui components**: https://ui.shadcn.com/docs/components"
  },
  {
    "path": "artifacts-builder/scripts/bundle-artifact.sh",
    "content": "#!/bin/bash\nset -e\n\necho \"📦 Bundling React app to single HTML artifact...\"\n\n# Check if we're in a project directory\nif [ ! -f \"package.json\" ]; then\n  echo \"❌ Error: No package.json found. Run this script from your project root.\"\n  exit 1\nfi\n\n# Check if index.html exists\nif [ ! -f \"index.html\" ]; then\n  echo \"❌ Error: No index.html found in project root.\"\n  echo \"   This script requires an index.html entry point.\"\n  exit 1\nfi\n\n# Install bundling dependencies\necho \"📦 Installing bundling dependencies...\"\npnpm add -D parcel @parcel/config-default parcel-resolver-tspaths html-inline\n\n# Create Parcel config with tspaths resolver\nif [ ! -f \".parcelrc\" ]; then\n  echo \"🔧 Creating Parcel configuration with path alias support...\"\n  cat > .parcelrc << 'EOF'\n{\n  \"extends\": \"@parcel/config-default\",\n  \"resolvers\": [\"parcel-resolver-tspaths\", \"...\"]\n}\nEOF\nfi\n\n# Clean previous build\necho \"🧹 Cleaning previous build...\"\nrm -rf dist bundle.html\n\n# Build with Parcel\necho \"🔨 Building with Parcel...\"\npnpm exec parcel build index.html --dist-dir dist --no-source-maps\n\n# Inline everything into single HTML\necho \"🎯 Inlining all assets into single HTML file...\"\npnpm exec html-inline dist/index.html > bundle.html\n\n# Get file size\nFILE_SIZE=$(du -h bundle.html | cut -f1)\n\necho \"\"\necho \"✅ Bundle complete!\"\necho \"📄 Output: bundle.html ($FILE_SIZE)\"\necho \"\"\necho \"You can now use this single HTML file as an artifact in Claude conversations.\"\necho \"To test locally: open bundle.html in your browser\""
  },
  {
    "path": "artifacts-builder/scripts/init-artifact.sh",
    "content": "#!/bin/bash\n\n# Exit on error\nset -e\n\n# Detect Node version\nNODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)\n\necho \"🔍 Detected Node.js version: $NODE_VERSION\"\n\nif [ \"$NODE_VERSION\" -lt 18 ]; then\n  echo \"❌ Error: Node.js 18 or higher is required\"\n  echo \"   Current version: $(node -v)\"\n  exit 1\nfi\n\n# Set Vite version based on Node version\nif [ \"$NODE_VERSION\" -ge 20 ]; then\n  VITE_VERSION=\"latest\"\n  echo \"✅ Using Vite latest (Node 20+)\"\nelse\n  VITE_VERSION=\"5.4.11\"\n  echo \"✅ Using Vite $VITE_VERSION (Node 18 compatible)\"\nfi\n\n# Detect OS and set sed syntax\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n  SED_INPLACE=\"sed -i ''\"\nelse\n  SED_INPLACE=\"sed -i\"\nfi\n\n# Check if pnpm is installed\nif ! command -v pnpm &> /dev/null; then\n  echo \"📦 pnpm not found. Installing pnpm...\"\n  npm install -g pnpm\nfi\n\n# Check if project name is provided\nif [ -z \"$1\" ]; then\n  echo \"❌ Usage: ./create-react-shadcn-complete.sh <project-name>\"\n  exit 1\nfi\n\nPROJECT_NAME=\"$1\"\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCOMPONENTS_TARBALL=\"$SCRIPT_DIR/shadcn-components.tar.gz\"\n\n# Check if components tarball exists\nif [ ! -f \"$COMPONENTS_TARBALL\" ]; then\n  echo \"❌ Error: shadcn-components.tar.gz not found in script directory\"\n  echo \"   Expected location: $COMPONENTS_TARBALL\"\n  exit 1\nfi\n\necho \"🚀 Creating new React + Vite project: $PROJECT_NAME\"\n\n# Create new Vite project (always use latest create-vite, pin vite version later)\npnpm create vite \"$PROJECT_NAME\" --template react-ts\n\n# Navigate into project directory\ncd \"$PROJECT_NAME\"\n\necho \"🧹 Cleaning up Vite template...\"\n$SED_INPLACE '/<link rel=\"icon\".*vite\\.svg/d' index.html\n$SED_INPLACE 's/<title>.*<\\/title>/<title>'\"$PROJECT_NAME\"'<\\/title>/' index.html\n\necho \"📦 Installing base dependencies...\"\npnpm install\n\n# Pin Vite version for Node 18\nif [ \"$NODE_VERSION\" -lt 20 ]; then\n  echo \"📌 Pinning Vite to $VITE_VERSION for Node 18 compatibility...\"\n  pnpm add -D vite@$VITE_VERSION\nfi\n\necho \"📦 Installing Tailwind CSS and dependencies...\"\npnpm install -D tailwindcss@3.4.1 postcss autoprefixer @types/node tailwindcss-animate\npnpm install class-variance-authority clsx tailwind-merge lucide-react next-themes\n\necho \"⚙️  Creating Tailwind and PostCSS configuration...\"\ncat > postcss.config.js << 'EOF'\nexport default {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\nEOF\n\necho \"📝 Configuring Tailwind with shadcn theme...\"\ncat > tailwind.config.js << 'EOF'\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  darkMode: [\"class\"],\n  content: [\n    \"./index.html\",\n    \"./src/**/*.{js,ts,jsx,tsx}\",\n  ],\n  theme: {\n    extend: {\n      colors: {\n        border: \"hsl(var(--border))\",\n        input: \"hsl(var(--input))\",\n        ring: \"hsl(var(--ring))\",\n        background: \"hsl(var(--background))\",\n        foreground: \"hsl(var(--foreground))\",\n        primary: {\n          DEFAULT: \"hsl(var(--primary))\",\n          foreground: \"hsl(var(--primary-foreground))\",\n        },\n        secondary: {\n          DEFAULT: \"hsl(var(--secondary))\",\n          foreground: \"hsl(var(--secondary-foreground))\",\n        },\n        destructive: {\n          DEFAULT: \"hsl(var(--destructive))\",\n          foreground: \"hsl(var(--destructive-foreground))\",\n        },\n        muted: {\n          DEFAULT: \"hsl(var(--muted))\",\n          foreground: \"hsl(var(--muted-foreground))\",\n        },\n        accent: {\n          DEFAULT: \"hsl(var(--accent))\",\n          foreground: \"hsl(var(--accent-foreground))\",\n        },\n        popover: {\n          DEFAULT: \"hsl(var(--popover))\",\n          foreground: \"hsl(var(--popover-foreground))\",\n        },\n        card: {\n          DEFAULT: \"hsl(var(--card))\",\n          foreground: \"hsl(var(--card-foreground))\",\n        },\n      },\n      borderRadius: {\n        lg: \"var(--radius)\",\n        md: \"calc(var(--radius) - 2px)\",\n        sm: \"calc(var(--radius) - 4px)\",\n      },\n      keyframes: {\n        \"accordion-down\": {\n          from: { height: \"0\" },\n          to: { height: \"var(--radix-accordion-content-height)\" },\n        },\n        \"accordion-up\": {\n          from: { height: \"var(--radix-accordion-content-height)\" },\n          to: { height: \"0\" },\n        },\n      },\n      animation: {\n        \"accordion-down\": \"accordion-down 0.2s ease-out\",\n        \"accordion-up\": \"accordion-up 0.2s ease-out\",\n      },\n    },\n  },\n  plugins: [require(\"tailwindcss-animate\")],\n}\nEOF\n\n# Add Tailwind directives and CSS variables to index.css\necho \"🎨 Adding Tailwind directives and CSS variables...\"\ncat > src/index.css << 'EOF'\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 0 0% 3.9%;\n    --card: 0 0% 100%;\n    --card-foreground: 0 0% 3.9%;\n    --popover: 0 0% 100%;\n    --popover-foreground: 0 0% 3.9%;\n    --primary: 0 0% 9%;\n    --primary-foreground: 0 0% 98%;\n    --secondary: 0 0% 96.1%;\n    --secondary-foreground: 0 0% 9%;\n    --muted: 0 0% 96.1%;\n    --muted-foreground: 0 0% 45.1%;\n    --accent: 0 0% 96.1%;\n    --accent-foreground: 0 0% 9%;\n    --destructive: 0 84.2% 60.2%;\n    --destructive-foreground: 0 0% 98%;\n    --border: 0 0% 89.8%;\n    --input: 0 0% 89.8%;\n    --ring: 0 0% 3.9%;\n    --radius: 0.5rem;\n  }\n\n  .dark {\n    --background: 0 0% 3.9%;\n    --foreground: 0 0% 98%;\n    --card: 0 0% 3.9%;\n    --card-foreground: 0 0% 98%;\n    --popover: 0 0% 3.9%;\n    --popover-foreground: 0 0% 98%;\n    --primary: 0 0% 98%;\n    --primary-foreground: 0 0% 9%;\n    --secondary: 0 0% 14.9%;\n    --secondary-foreground: 0 0% 98%;\n    --muted: 0 0% 14.9%;\n    --muted-foreground: 0 0% 63.9%;\n    --accent: 0 0% 14.9%;\n    --accent-foreground: 0 0% 98%;\n    --destructive: 0 62.8% 30.6%;\n    --destructive-foreground: 0 0% 98%;\n    --border: 0 0% 14.9%;\n    --input: 0 0% 14.9%;\n    --ring: 0 0% 83.1%;\n  }\n}\n\n@layer base {\n  * {\n    @apply border-border;\n  }\n  body {\n    @apply bg-background text-foreground;\n  }\n}\nEOF\n\n# Add path aliases to tsconfig.json\necho \"🔧 Adding path aliases to tsconfig.json...\"\nnode -e \"\nconst fs = require('fs');\nconst config = JSON.parse(fs.readFileSync('tsconfig.json', 'utf8'));\nconfig.compilerOptions = config.compilerOptions || {};\nconfig.compilerOptions.baseUrl = '.';\nconfig.compilerOptions.paths = { '@/*': ['./src/*'] };\nfs.writeFileSync('tsconfig.json', JSON.stringify(config, null, 2));\n\"\n\n# Add path aliases to tsconfig.app.json\necho \"🔧 Adding path aliases to tsconfig.app.json...\"\nnode -e \"\nconst fs = require('fs');\nconst path = 'tsconfig.app.json';\nconst content = fs.readFileSync(path, 'utf8');\n// Remove comments manually\nconst lines = content.split('\\n').filter(line => !line.trim().startsWith('//'));\nconst jsonContent = lines.join('\\n');\nconst config = JSON.parse(jsonContent.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/,(\\s*[}\\]])/g, '\\$1'));\nconfig.compilerOptions = config.compilerOptions || {};\nconfig.compilerOptions.baseUrl = '.';\nconfig.compilerOptions.paths = { '@/*': ['./src/*'] };\nfs.writeFileSync(path, JSON.stringify(config, null, 2));\n\"\n\n# Update vite.config.ts\necho \"⚙️  Updating Vite configuration...\"\ncat > vite.config.ts << 'EOF'\nimport path from \"path\";\nimport react from \"@vitejs/plugin-react\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n  plugins: [react()],\n  resolve: {\n    alias: {\n      \"@\": path.resolve(__dirname, \"./src\"),\n    },\n  },\n});\nEOF\n\n# Install all shadcn/ui dependencies\necho \"📦 Installing shadcn/ui dependencies...\"\npnpm install @radix-ui/react-accordion @radix-ui/react-aspect-ratio @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-collapsible @radix-ui/react-context-menu @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-hover-card @radix-ui/react-label @radix-ui/react-menubar @radix-ui/react-navigation-menu @radix-ui/react-popover @radix-ui/react-progress @radix-ui/react-radio-group @radix-ui/react-scroll-area @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slider @radix-ui/react-slot @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-toast @radix-ui/react-toggle @radix-ui/react-toggle-group @radix-ui/react-tooltip\npnpm install sonner cmdk vaul embla-carousel-react react-day-picker react-resizable-panels date-fns react-hook-form @hookform/resolvers zod\n\n# Extract shadcn components from tarball\necho \"📦 Extracting shadcn/ui components...\"\ntar -xzf \"$COMPONENTS_TARBALL\" -C src/\n\n# Create components.json for reference\necho \"📝 Creating components.json config...\"\ncat > components.json << 'EOF'\n{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": false,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"tailwind.config.js\",\n    \"css\": \"src/index.css\",\n    \"baseColor\": \"slate\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\",\n    \"utils\": \"@/lib/utils\",\n    \"ui\": \"@/components/ui\",\n    \"lib\": \"@/lib\",\n    \"hooks\": \"@/hooks\"\n  }\n}\nEOF\n\necho \"✅ Setup complete! You can now use Tailwind CSS and shadcn/ui in your project.\"\necho \"\"\necho \"📦 Included components (40+ total):\"\necho \"  - accordion, alert, aspect-ratio, avatar, badge, breadcrumb\"\necho \"  - button, calendar, card, carousel, checkbox, collapsible\"\necho \"  - command, context-menu, dialog, drawer, dropdown-menu\"\necho \"  - form, hover-card, input, label, menubar, navigation-menu\"\necho \"  - popover, progress, radio-group, resizable, scroll-area\"\necho \"  - select, separator, sheet, skeleton, slider, sonner\"\necho \"  - switch, table, tabs, textarea, toast, toggle, toggle-group, tooltip\"\necho \"\"\necho \"To start developing:\"\necho \"  cd $PROJECT_NAME\"\necho \"  pnpm dev\"\necho \"\"\necho \"📚 Import components like:\"\necho \"  import { Button } from '@/components/ui/button'\"\necho \"  import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'\"\necho \"  import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog'\"\n"
  },
  {
    "path": "brand-guidelines/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "brand-guidelines/SKILL.md",
    "content": "---\nname: brand-guidelines\ndescription: Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Anthropic Brand Styling\n\n## Overview\n\nTo access Anthropic's official brand identity and style resources, use this skill.\n\n**Keywords**: branding, corporate identity, visual identity, post-processing, styling, brand colors, typography, Anthropic brand, visual formatting, visual design\n\n## Brand Guidelines\n\n### Colors\n\n**Main Colors:**\n\n- Dark: `#141413` - Primary text and dark backgrounds\n- Light: `#faf9f5` - Light backgrounds and text on dark\n- Mid Gray: `#b0aea5` - Secondary elements\n- Light Gray: `#e8e6dc` - Subtle backgrounds\n\n**Accent Colors:**\n\n- Orange: `#d97757` - Primary accent\n- Blue: `#6a9bcc` - Secondary accent\n- Green: `#788c5d` - Tertiary accent\n\n### Typography\n\n- **Headings**: Poppins (with Arial fallback)\n- **Body Text**: Lora (with Georgia fallback)\n- **Note**: Fonts should be pre-installed in your environment for best results\n\n## Features\n\n### Smart Font Application\n\n- Applies Poppins font to headings (24pt and larger)\n- Applies Lora font to body text\n- Automatically falls back to Arial/Georgia if custom fonts unavailable\n- Preserves readability across all systems\n\n### Text Styling\n\n- Headings (24pt+): Poppins font\n- Body text: Lora font\n- Smart color selection based on background\n- Preserves text hierarchy and formatting\n\n### Shape and Accent Colors\n\n- Non-text shapes use accent colors\n- Cycles through orange, blue, and green accents\n- Maintains visual interest while staying on-brand\n\n## Technical Details\n\n### Font Management\n\n- Uses system-installed Poppins and Lora fonts when available\n- Provides automatic fallback to Arial (headings) and Georgia (body)\n- No font installation required - works with existing system fonts\n- For best results, pre-install Poppins and Lora fonts in your environment\n\n### Color Application\n\n- Uses RGB color values for precise brand matching\n- Applied via python-pptx's RGBColor class\n- Maintains color fidelity across different systems\n"
  },
  {
    "path": "canvas-design/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "canvas-design/SKILL.md",
    "content": "---\nname: canvas-design\ndescription: Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.\nlicense: Complete terms in LICENSE.txt\n---\n\nThese are instructions for creating design philosophies - aesthetic movements that are then EXPRESSED VISUALLY. Output only .md files, .pdf files, and .png files.\n\nComplete this in two steps:\n1. Design Philosophy Creation (.md file)\n2. Express by creating it on a canvas (.pdf file or .png file)\n\nFirst, undertake this task:\n\n## DESIGN PHILOSOPHY CREATION\n\nTo begin, create a VISUAL PHILOSOPHY (not layouts or templates) that will be interpreted through:\n- Form, space, color, composition\n- Images, graphics, shapes, patterns\n- Minimal text as visual accent\n\n### THE CRITICAL UNDERSTANDING\n- What is received: Some subtle input or instructions by the user that should be taken into account, but used as a foundation; it should not constrain creative freedom.\n- What is created: A design philosophy/aesthetic movement.\n- What happens next: Then, the same version receives the philosophy and EXPRESSES IT VISUALLY - creating artifacts that are 90% visual design, 10% essential text.\n\nConsider this approach:\n- Write a manifesto for an art movement\n- The next phase involves making the artwork\n\nThe philosophy must emphasize: Visual expression. Spatial communication. Artistic interpretation. Minimal words.\n\n### HOW TO GENERATE A VISUAL PHILOSOPHY\n\n**Name the movement** (1-2 words): \"Brutalist Joy\" / \"Chromatic Silence\" / \"Metabolist Dreams\"\n\n**Articulate the philosophy** (4-6 paragraphs - concise but complete):\n\nTo capture the VISUAL essence, express how the philosophy manifests through:\n- Space and form\n- Color and material\n- Scale and rhythm\n- Composition and balance\n- Visual hierarchy\n\n**CRITICAL GUIDELINES:**\n- **Avoid redundancy**: Each design aspect should be mentioned once. Avoid repeating points about color theory, spatial relationships, or typographic principles unless adding new depth.\n- **Emphasize craftsmanship REPEATEDLY**: The philosophy MUST stress multiple times that the final work should appear as though it took countless hours to create, was labored over with care, and comes from someone at the absolute top of their field. This framing is essential - repeat phrases like \"meticulously crafted,\" \"the product of deep expertise,\" \"painstaking attention,\" \"master-level execution.\"\n- **Leave creative space**: Remain specific about the aesthetic direction, but concise enough that the next Claude has room to make interpretive choices also at a extremely high level of craftmanship.\n\nThe philosophy must guide the next version to express ideas VISUALLY, not through text. Information lives in design, not paragraphs.\n\n### PHILOSOPHY EXAMPLES\n\n**\"Concrete Poetry\"**\nPhilosophy: Communication through monumental form and bold geometry.\nVisual expression: Massive color blocks, sculptural typography (huge single words, tiny labels), Brutalist spatial divisions, Polish poster energy meets Le Corbusier. Ideas expressed through visual weight and spatial tension, not explanation. Text as rare, powerful gesture - never paragraphs, only essential words integrated into the visual architecture. Every element placed with the precision of a master craftsman.\n\n**\"Chromatic Language\"**\nPhilosophy: Color as the primary information system.\nVisual expression: Geometric precision where color zones create meaning. Typography minimal - small sans-serif labels letting chromatic fields communicate. Think Josef Albers' interaction meets data visualization. Information encoded spatially and chromatically. Words only to anchor what color already shows. The result of painstaking chromatic calibration.\n\n**\"Analog Meditation\"**\nPhilosophy: Quiet visual contemplation through texture and breathing room.\nVisual expression: Paper grain, ink bleeds, vast negative space. Photography and illustration dominate. Typography whispered (small, restrained, serving the visual). Japanese photobook aesthetic. Images breathe across pages. Text appears sparingly - short phrases, never explanatory blocks. Each composition balanced with the care of a meditation practice.\n\n**\"Organic Systems\"**\nPhilosophy: Natural clustering and modular growth patterns.\nVisual expression: Rounded forms, organic arrangements, color from nature through architecture. Information shown through visual diagrams, spatial relationships, iconography. Text only for key labels floating in space. The composition tells the story through expert spatial orchestration.\n\n**\"Geometric Silence\"**\nPhilosophy: Pure order and restraint.\nVisual expression: Grid-based precision, bold photography or stark graphics, dramatic negative space. Typography precise but minimal - small essential text, large quiet zones. Swiss formalism meets Brutalist material honesty. Structure communicates, not words. Every alignment the work of countless refinements.\n\n*These are condensed examples. The actual design philosophy should be 4-6 substantial paragraphs.*\n\n### ESSENTIAL PRINCIPLES\n- **VISUAL PHILOSOPHY**: Create an aesthetic worldview to be expressed through design\n- **MINIMAL TEXT**: Always emphasize that text is sparse, essential-only, integrated as visual element - never lengthy\n- **SPATIAL EXPRESSION**: Ideas communicate through space, form, color, composition - not paragraphs\n- **ARTISTIC FREEDOM**: The next Claude interprets the philosophy visually - provide creative room\n- **PURE DESIGN**: This is about making ART OBJECTS, not documents with decoration\n- **EXPERT CRAFTSMANSHIP**: Repeatedly emphasize the final work must look meticulously crafted, labored over with care, the product of countless hours by someone at the top of their field\n\n**The design philosophy should be 4-6 paragraphs long.** Fill it with poetic design philosophy that brings together the core vision. Avoid repeating the same points. Keep the design philosophy generic without mentioning the intention of the art, as if it can be used wherever. Output the design philosophy as a .md file.\n\n---\n\n## DEDUCING THE SUBTLE REFERENCE\n\n**CRITICAL STEP**: Before creating the canvas, identify the subtle conceptual thread from the original request.\n\n**THE ESSENTIAL PRINCIPLE**:\nThe topic is a **subtle, niche reference embedded within the art itself** - not always literal, always sophisticated. Someone familiar with the subject should feel it intuitively, while others simply experience a masterful abstract composition. The design philosophy provides the aesthetic language. The deduced topic provides the soul - the quiet conceptual DNA woven invisibly into form, color, and composition.\n\nThis is **VERY IMPORTANT**: The reference must be refined so it enhances the work's depth without announcing itself. Think like a jazz musician quoting another song - only those who know will catch it, but everyone appreciates the music.\n\n---\n\n## CANVAS CREATION\n\nWith both the philosophy and the conceptual framework established, express it on a canvas. Take a moment to gather thoughts and clear the mind. Use the design philosophy created and the instructions below to craft a masterpiece, embodying all aspects of the philosophy with expert craftsmanship.\n\n**IMPORTANT**: For any type of content, even if the user requests something for a movie/game/book, the approach should still be sophisticated. Never lose sight of the idea that this should be art, not something that's cartoony or amateur.\n\nTo create museum or magazine quality work, use the design philosophy as the foundation. Create one single page, highly visual, design-forward PDF or PNG output (unless asked for more pages). Generally use repeating patterns and perfect shapes. Treat the abstract philosophical design as if it were a scientific bible, borrowing the visual language of systematic observation—dense accumulation of marks, repeated elements, or layered patterns that build meaning through patient repetition and reward sustained viewing. Add sparse, clinical typography and systematic reference markers that suggest this could be a diagram from an imaginary discipline, treating the invisible subject with the same reverence typically reserved for documenting observable phenomena. Anchor the piece with simple phrase(s) or details positioned subtly, using a limited color palette that feels intentional and cohesive. Embrace the paradox of using analytical visual language to express ideas about human experience: the result should feel like an artifact that proves something ephemeral can be studied, mapped, and understood through careful attention. This is true art. \n\n**Text as a contextual element**: Text is always minimal and visual-first, but let context guide whether that means whisper-quiet labels or bold typographic gestures. A punk venue poster might have larger, more aggressive type than a minimalist ceramics studio identity. Most of the time, font should be thin. All use of fonts must be design-forward and prioritize visual communication. Regardless of text scale, nothing falls off the page and nothing overlaps. Every element must be contained within the canvas boundaries with proper margins. Check carefully that all text, graphics, and visual elements have breathing room and clear separation. This is non-negotiable for professional execution. **IMPORTANT: Use different fonts if writing text. Search the `./canvas-fonts` directory. Regardless of approach, sophistication is non-negotiable.**\n\nDownload and use whatever fonts are needed to make this a reality. Get creative by making the typography actually part of the art itself -- if the art is abstract, bring the font onto the canvas, not typeset digitally.\n\nTo push boundaries, follow design instinct/intuition while using the philosophy as a guiding principle. Embrace ultimate design freedom and choice. Push aesthetics and design to the frontier. \n\n**CRITICAL**: To achieve human-crafted quality (not AI-generated), create work that looks like it took countless hours. Make it appear as though someone at the absolute top of their field labored over every detail with painstaking care. Ensure the composition, spacing, color choices, typography - everything screams expert-level craftsmanship. Double-check that nothing overlaps, formatting is flawless, every detail perfect. Create something that could be shown to people to prove expertise and rank as undeniably impressive.\n\nOutput the final result as a single, downloadable .pdf or .png file, alongside the design philosophy used as a .md file.\n\n---\n\n## FINAL STEP\n\n**IMPORTANT**: The user ALREADY said \"It isn't perfect enough. It must be pristine, a masterpiece if craftsmanship, as if it were about to be displayed in a museum.\"\n\n**CRITICAL**: To refine the work, avoid adding more graphics; instead refine what has been created and make it extremely crisp, respecting the design philosophy and the principles of minimalism entirely. Rather than adding a fun filter or refactoring a font, consider how to make the existing composition more cohesive with the art. If the instinct is to call a new function or draw a new shape, STOP and instead ask: \"How can I make what's already here more of a piece of art?\"\n\nTake a second pass. Go back to the code and refine/polish further to make this a philosophically designed masterpiece.\n\n## MULTI-PAGE OPTION\n\nTo create additional pages when requested, create more creative pages along the same lines as the design philosophy but distinctly different as well. Bundle those pages in the same .pdf or many .pngs. Treat the first page as just a single page in a whole coffee table book waiting to be filled. Make the next pages unique twists and memories of the original. Have them almost tell a story in a very tasteful way. Exercise full creative freedom."
  },
  {
    "path": "canvas-design/canvas-fonts/ArsenalSC-OFL.txt",
    "content": "Copyright 2012 The Arsenal Project Authors (andrij.design@gmail.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/BigShoulders-OFL.txt",
    "content": "Copyright 2019 The Big Shoulders Project Authors (https://github.com/xotypeco/big_shoulders)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Boldonse-OFL.txt",
    "content": "Copyright 2024 The Boldonse Project Authors (https://github.com/googlefonts/boldonse)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt",
    "content": "Copyright 2022 The Bricolage Grotesque Project Authors (https://github.com/ateliertriay/bricolage)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/CrimsonPro-OFL.txt",
    "content": "Copyright 2018 The Crimson Pro Project Authors (https://github.com/Fonthausen/CrimsonPro)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/DMMono-OFL.txt",
    "content": "Copyright 2020 The DM Mono Project Authors (https://www.github.com/googlefonts/dm-mono)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/EricaOne-OFL.txt",
    "content": "Copyright (c) 2011 by LatinoType Limitada (luciano@latinotype.com), \nwith Reserved Font Names \"Erica One\"\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/GeistMono-OFL.txt",
    "content": "Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font.git)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Gloock-OFL.txt",
    "content": "Copyright 2022 The Gloock Project Authors (https://github.com/duartp/gloock)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/IBMPlexMono-OFL.txt",
    "content": "Copyright © 2017 IBM Corp. with Reserved Font Name \"Plex\"\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/InstrumentSans-OFL.txt",
    "content": "Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Italiana-OFL.txt",
    "content": "Copyright (c) 2011, Santiago Orozco (hi@typemade.mx), with Reserved Font Name \"Italiana\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/JetBrainsMono-OFL.txt",
    "content": "Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Jura-OFL.txt",
    "content": "Copyright 2019 The Jura Project Authors (https://github.com/ossobuffo/jura)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/LibreBaskerville-OFL.txt",
    "content": "Copyright 2012 The Libre Baskerville Project Authors (https://github.com/impallari/Libre-Baskerville) with Reserved Font Name Libre Baskerville.\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Lora-OFL.txt",
    "content": "Copyright 2011 The Lora Project Authors (https://github.com/cyrealtype/Lora-Cyrillic), with Reserved Font Name \"Lora\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/NationalPark-OFL.txt",
    "content": "Copyright 2025 The National Park Project Authors (https://github.com/benhoepner/National-Park)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt",
    "content": "Copyright (c) 2010, Kimberly Geswein (kimberlygeswein.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Outfit-OFL.txt",
    "content": "Copyright 2021 The Outfit Project Authors (https://github.com/Outfitio/Outfit-Fonts)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/PixelifySans-OFL.txt",
    "content": "Copyright 2021 The Pixelify Sans Project Authors (https://github.com/eifetx/Pixelify-Sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/PoiretOne-OFL.txt",
    "content": "Copyright (c) 2011, Denis Masharov (denis.masharov@gmail.com)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/RedHatMono-OFL.txt",
    "content": "Copyright 2024 The Red Hat Project Authors (https://github.com/RedHatOfficial/RedHatFont)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Silkscreen-OFL.txt",
    "content": "Copyright 2001 The Silkscreen Project Authors (https://github.com/googlefonts/silkscreen)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/SmoochSans-OFL.txt",
    "content": "Copyright 2016 The Smooch Sans Project Authors (https://github.com/googlefonts/smooch-sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/Tektur-OFL.txt",
    "content": "Copyright 2023 The Tektur Project Authors (https://www.github.com/hyvyys/Tektur)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/WorkSans-OFL.txt",
    "content": "Copyright 2019 The Work Sans Project Authors (https://github.com/weiweihuanghuang/Work-Sans)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "canvas-design/canvas-fonts/YoungSerif-OFL.txt",
    "content": "Copyright 2023 The Young Serif Project Authors (https://github.com/noirblancrouge/YoungSerif)\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttps://openfontlicense.org\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "changelog-generator/SKILL.md",
    "content": "---\nname: changelog-generator\ndescription: Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.\n---\n\n# Changelog Generator\n\nThis skill transforms technical git commits into polished, user-friendly changelogs that your customers and users will actually understand and appreciate.\n\n## When to Use This Skill\n\n- Preparing release notes for a new version\n- Creating weekly or monthly product update summaries\n- Documenting changes for customers\n- Writing changelog entries for app store submissions\n- Generating update notifications\n- Creating internal release documentation\n- Maintaining a public changelog/product updates page\n\n## What This Skill Does\n\n1. **Scans Git History**: Analyzes commits from a specific time period or between versions\n2. **Categorizes Changes**: Groups commits into logical categories (features, improvements, bug fixes, breaking changes, security)\n3. **Translates Technical → User-Friendly**: Converts developer commits into customer language\n4. **Formats Professionally**: Creates clean, structured changelog entries\n5. **Filters Noise**: Excludes internal commits (refactoring, tests, etc.)\n6. **Follows Best Practices**: Applies changelog guidelines and your brand voice\n\n## How to Use\n\n### Basic Usage\n\nFrom your project repository:\n\n```\nCreate a changelog from commits since last release\n```\n\n```\nGenerate changelog for all commits from the past week\n```\n\n```\nCreate release notes for version 2.5.0\n```\n\n### With Specific Date Range\n\n```\nCreate a changelog for all commits between March 1 and March 15\n```\n\n### With Custom Guidelines\n\n```\nCreate a changelog for commits since v2.4.0, using my changelog \nguidelines from CHANGELOG_STYLE.md\n```\n\n## Example\n\n**User**: \"Create a changelog for commits from the past 7 days\"\n\n**Output**:\n```markdown\n# Updates - Week of March 10, 2024\n\n## ✨ New Features\n\n- **Team Workspaces**: Create separate workspaces for different \n  projects. Invite team members and keep everything organized.\n\n- **Keyboard Shortcuts**: Press ? to see all available shortcuts. \n  Navigate faster without touching your mouse.\n\n## 🔧 Improvements\n\n- **Faster Sync**: Files now sync 2x faster across devices\n- **Better Search**: Search now includes file contents, not just titles\n\n## 🐛 Fixes\n\n- Fixed issue where large images wouldn't upload\n- Resolved timezone confusion in scheduled posts\n- Corrected notification badge count\n```\n\n**Inspired by:** Manik Aggarwal's use case from Lenny's Newsletter\n\n## Tips\n\n- Run from your git repository root\n- Specify date ranges for focused changelogs\n- Use your CHANGELOG_STYLE.md for consistent formatting\n- Review and adjust the generated changelog before publishing\n- Save output directly to CHANGELOG.md\n\n## Related Use Cases\n\n- Creating GitHub release notes\n- Writing app store update descriptions\n- Generating email updates for users\n- Creating social media announcement posts\n\n"
  },
  {
    "path": "competitive-ads-extractor/SKILL.md",
    "content": "---\nname: competitive-ads-extractor\ndescription: Extracts and analyzes competitors' ads from ad libraries (Facebook, LinkedIn, etc.) to understand what messaging, problems, and creative approaches are working. Helps inspire and improve your own ad campaigns.\n---\n\n# Competitive Ads Extractor\n\nThis skill extracts your competitors' ads from ad libraries and analyzes what's working—the problems they're highlighting, use cases they're targeting, and copy/creative that's resonating.\n\n## When to Use This Skill\n\n- Researching competitor ad strategies\n- Finding inspiration for your own ads\n- Understanding market positioning\n- Identifying successful ad patterns\n- Analyzing messaging that works\n- Discovering new use cases or pain points\n- Planning ad campaigns with proven concepts\n\n## What This Skill Does\n\n1. **Extracts Ads**: Scrapes ads from Facebook Ad Library, LinkedIn, etc.\n2. **Captures Screenshots**: Saves visual copies of all ads\n3. **Analyzes Messaging**: Identifies problems, use cases, and value props\n4. **Categorizes Ads**: Groups by theme, audience, or format\n5. **Identifies Patterns**: Finds common successful approaches\n6. **Provides Insights**: Explains why certain ads likely perform well\n\n## How to Use\n\n### Basic Extraction\n\n```\nExtract all current ads from [Competitor Name] on Facebook Ad Library\n```\n\n```\nScrape ads from [Company] and analyze their messaging\n```\n\n### Specific Analysis\n\n```\nGet all ads from [Competitor] focusing on their messaging \nabout [specific problem]. What pain points are they highlighting?\n```\n\n### Competitive Set\n\n```\nExtract ads from these 5 competitors: [list]. \nCompare their approaches and tell me what's working.\n```\n\n### Specific Platform\n\n```\nGet LinkedIn ads from [Competitor] and analyze their \nB2B positioning strategy\n```\n\n## Example\n\n**User**: \"Extract ads from Notion on Facebook Ad Library and tell me what messaging is working for them.\"\n\n**Process**:\n```\nAccessing Facebook Ad Library...\nSearching for: Notion\nFound: 23 active ads\n\nExtracting screenshots...\n[████████████████████] 100%\n\nSaved to: competitor-ads/notion/\n- ad-001-collaboration.png\n- ad-002-productivity.png\n- ad-003-templates.png\n...\n\nAnalyzing messaging...\n```\n\n**Output**:\n```\n# Notion Ad Analysis\n\n## Overview\n- Total Ads: 23 active\n- Primary Themes: Productivity (35%), Collaboration (30%), \n  Templates (20%), AI Features (15%)\n- Ad Formats: Static images (60%), Video (40%)\n- CTA Patterns: \"Try for free\", \"Get started\"\n\n## Key Problems They're Highlighting\n\n1. **Scattered Information** (8 ads)\n   Copy: \"Stop switching between 10 different tools\"\n   Why it works: Direct pain point many teams face\n\n2. **Meeting Overload** (5 ads)\n   Copy: \"Replace unnecessary meetings with async updates\"\n   Why it works: Post-COVID remote work pain point\n\n3. **Lost Documentation** (4 ads)\n   Copy: \"Never ask 'where is that doc?' again\"\n   Why it works: Universal workplace frustration\n\n## Successful Creative Patterns\n\n### Pattern 1: Before/After Split\n- Shows chaotic tool landscape → Clean Notion workspace\n- Used in 6 high-performing ads\n- Visual metaphor is immediately clear\n\n### Pattern 2: Feature Showcase\n- GIF of actual product usage\n- Shows specific feature in 5 seconds\n- Used for new features (AI, templates)\n\n### Pattern 3: Social Proof\n- \"Join 20M users\" messaging\n- Customer logos\n- Used in 4 ads targeting enterprise\n\n## Copy That's Working\n\nBest Headlines:\n1. \"Your team's knowledge, finally in one place\"\n   → Benefit-focused, addresses pain directly\n   \n2. \"The all-in-one workspace\"\n   → Clear positioning, broad appeal\n   \n3. \"AI that actually helps you work\"\n   → Addresses AI skepticism, practical angle\n\nBest Body Copy Patterns:\n- Short sentences (under 10 words)\n- Focus on outcomes not features\n- Include specific numbers (\"Cut meetings by 50%\")\n\n## Audience Targeting Insights\n\nBased on ad variations:\n- Startup founders: Solo productivity angle\n- Team leads: Collaboration and alignment\n- Enterprise: Security and compliance mentions\n- Students: Free plan, templates, organization\n\n## Recommendations for Your Ads\n\n1. **Test the \"tool sprawl\" pain point**\n   → Strong resonance based on their ad frequency\n\n2. **Use product screenshots over abstract visuals**\n   → All their top ads show actual UI\n\n3. **Lead with the problem, not the solution**\n   → \"Tired of X?\" performs better than \"Introducing Y\"\n\n4. **Keep copy under 100 characters**\n   → Their shortest ads seem most frequent\n\n5. **Test before/after visual formats**\n   → Proven pattern in their creative\n\n## Files Saved\n- All ads: ~/competitor-ads/notion/\n- Analysis: ~/competitor-ads/notion/analysis.md\n- Best performers: ~/competitor-ads/notion/top-10/\n```\n\n**Inspired by:** Sumant Subrahmanya's use case from Lenny's Newsletter\n\n## What You Can Learn\n\n### Messaging Analysis\n- What problems they emphasize\n- How they position against competition\n- Value propositions that resonate\n- Target audience segments\n\n### Creative Patterns\n- Visual styles that work\n- Video vs. static image performance\n- Color schemes and branding\n- Layout patterns\n\n### Copy Formulas\n- Headline structures\n- Call-to-action patterns\n- Length and tone\n- Emotional triggers\n\n### Campaign Strategy\n- Seasonal campaigns\n- Product launch approaches\n- Feature announcement tactics\n- Retargeting patterns\n\n## Best Practices\n\n### Legal & Ethical\n✓ Only use for research and inspiration\n✓ Don't copy ads directly\n✓ Respect intellectual property\n✓ Use insights to inform original creative\n✗ Don't plagiarize copy or steal designs\n\n### Analysis Tips\n1. **Look for patterns**: What themes repeat?\n2. **Track over time**: Save ads monthly to see evolution\n3. **Test hypotheses**: Adapt successful patterns for your brand\n4. **Segment by audience**: Different messages for different targets\n5. **Compare platforms**: LinkedIn vs Facebook messaging differs\n\n## Advanced Features\n\n### Trend Tracking\n```\nCompare [Competitor]'s ads from Q1 vs Q2. \nWhat messaging has changed?\n```\n\n### Multi-Competitor Analysis\n```\nExtract ads from [Company A], [Company B], [Company C]. \nWhat are the common patterns? Where do they differ?\n```\n\n### Industry Benchmarks\n```\nShow me ad patterns across the top 10 project management \ntools. What problems do they all focus on?\n```\n\n### Format Analysis\n```\nAnalyze video ads vs static image ads from [Competitor]. \nWhich gets more engagement? (if data available)\n```\n\n## Common Workflows\n\n### Ad Campaign Planning\n1. Extract competitor ads\n2. Identify successful patterns\n3. Note gaps in their messaging\n4. Brainstorm unique angles\n5. Draft test ad variations\n\n### Positioning Research\n1. Get ads from 5 competitors\n2. Map their positioning\n3. Find underserved angles\n4. Develop differentiated messaging\n5. Test against their approaches\n\n### Creative Inspiration\n1. Extract ads by theme\n2. Analyze visual patterns\n3. Note color and layout trends\n4. Adapt successful patterns\n5. Create original variations\n\n## Tips for Success\n\n1. **Regular Monitoring**: Check monthly for changes\n2. **Broad Research**: Look at adjacent competitors too\n3. **Save Everything**: Build a reference library\n4. **Test Insights**: Run your own experiments\n5. **Track Performance**: A/B test inspired concepts\n6. **Stay Original**: Use for inspiration, not copying\n7. **Multiple Platforms**: Compare Facebook, LinkedIn, TikTok, etc.\n\n## Output Formats\n\n- **Screenshots**: All ads saved as images\n- **Analysis Report**: Markdown summary of insights\n- **Spreadsheet**: CSV with ad copy, CTAs, themes\n- **Presentation**: Visual deck of top performers\n- **Pattern Library**: Categorized by approach\n\n## Related Use Cases\n\n- Writing better ad copy for your campaigns\n- Understanding market positioning\n- Finding content gaps in your messaging\n- Discovering new use cases for your product\n- Planning product marketing strategy\n- Inspiring social media content\n\n"
  },
  {
    "path": "composio-skills/-21risk-automation/SKILL.md",
    "content": "---\nname: -21risk-automation\ndescription: \"Automate 21risk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# 21risk Automation via Rube MCP\n\nAutomate 21risk operations through Composio's 21risk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/_21risk](https://composio.dev/toolkits/_21risk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active 21risk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `_21risk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `_21risk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"21risk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific 21risk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"_21risk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with 21risk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `_21risk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/-2chat-automation/SKILL.md",
    "content": "---\nname: -2chat-automation\ndescription: \"Automate 2chat tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# 2chat Automation via Rube MCP\n\nAutomate 2chat operations through Composio's 2chat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/_2chat](https://composio.dev/toolkits/_2chat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active 2chat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `_2chat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `_2chat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"2chat operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific 2chat task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"_2chat\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with 2chat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `_2chat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/.claude-plugin/marketplace.json",
    "content": "{\n  \"$schema\": \"https://anthropic.com/claude-code/marketplace.schema.json\",\n  \"name\": \"awesome-claude-skills\",\n  \"version\": \"2.0.0\",\n  \"description\": \"A curated marketplace of practical Claude Skills for enhancing productivity across Claude.ai, Claude Code, and the Claude API\",\n  \"owner\": {\n    \"name\": \"ComposioHQ\",\n    \"email\": \"tech@composio.dev\"\n  },\n  \"plugins\": [\n    {\n      \"name\": \"brand-guidelines\",\n      \"description\": \"Applies Anthropic's official brand colors and typography to artifacts for consistent visual identity and professional design standards.\",\n      \"source\": \"./brand-guidelines\",\n      \"category\": \"business-marketing\"\n    },\n    {\n      \"name\": \"competitive-ads-extractor\",\n      \"description\": \"Extracts and analyzes competitors' ads from ad libraries to understand messaging and creative approaches that resonate.\",\n      \"source\": \"./competitive-ads-extractor\",\n      \"category\": \"business-marketing\"\n    },\n    {\n      \"name\": \"domain-name-brainstormer\",\n      \"description\": \"Generates creative domain name ideas and checks availability across multiple TLDs including .com, .io, .dev, and .ai extensions.\",\n      \"source\": \"./domain-name-brainstormer\",\n      \"category\": \"business-marketing\"\n    },\n    {\n      \"name\": \"internal-comms\",\n      \"description\": \"Helps write internal communications including 3P updates, company newsletters, FAQs, status reports, and project updates using company-specific formats.\",\n      \"source\": \"./internal-comms\",\n      \"category\": \"business-marketing\"\n    },\n    {\n      \"name\": \"lead-research-assistant\",\n      \"description\": \"Identifies and qualifies high-quality leads by analyzing your product, searching for target companies, and providing actionable outreach strategies.\",\n      \"source\": \"./lead-research-assistant\",\n      \"category\": \"business-marketing\"\n    },\n    {\n      \"name\": \"content-research-writer\",\n      \"description\": \"Assists in writing high-quality content by conducting research, adding citations, improving hooks, and providing section-by-section feedback.\",\n      \"source\": \"./content-research-writer\",\n      \"category\": \"communication-writing\"\n    },\n    {\n      \"name\": \"meeting-insights-analyzer\",\n      \"description\": \"Analyzes meeting transcripts to uncover behavioral patterns including conflict avoidance, speaking ratios, filler words, and leadership style.\",\n      \"source\": \"./meeting-insights-analyzer\",\n      \"category\": \"communication-writing\"\n    },\n    {\n      \"name\": \"twitter-algorithm-optimizer\",\n      \"description\": \"Analyze and optimize tweets for maximum reach using Twitter's open-source algorithm insights. Rewrite and edit tweets to improve engagement and visibility.\",\n      \"source\": \"./twitter-algorithm-optimizer\",\n      \"category\": \"communication-writing\"\n    },\n    {\n      \"name\": \"canvas-design\",\n      \"description\": \"Creates beautiful visual art in PNG and PDF documents using design philosophy and aesthetic principles for posters, designs, and static pieces.\",\n      \"source\": \"./canvas-design\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"image-enhancer\",\n      \"description\": \"Improves image and screenshot quality by enhancing resolution, sharpness, and clarity for professional presentations and documentation.\",\n      \"source\": \"./image-enhancer\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"slack-gif-creator\",\n      \"description\": \"Creates animated GIFs optimized for Slack with validators for size constraints and composable animation primitives.\",\n      \"source\": \"./slack-gif-creator\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"theme-factory\",\n      \"description\": \"Applies professional font and color themes to artifacts including slides, docs, reports, and HTML landing pages with 10 pre-set themes.\",\n      \"source\": \"./theme-factory\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"video-downloader\",\n      \"description\": \"Downloads videos from YouTube and other platforms for offline viewing, editing, or archival with support for various formats and quality options.\",\n      \"source\": \"./video-downloader\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"algorithmic-art\",\n      \"description\": \"Creates algorithmic art and generative designs using computational creativity techniques.\",\n      \"source\": \"./algorithmic-art\",\n      \"category\": \"creative-media\"\n    },\n    {\n      \"name\": \"artifacts-builder\",\n      \"description\": \"Builds elaborate, multi-component Claude.ai HTML artifacts using modern frontend technologies including React, Tailwind CSS, and shadcn/ui.\",\n      \"source\": \"./artifacts-builder\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"changelog-generator\",\n      \"description\": \"Automatically creates user-facing changelogs from git commits by analyzing history and transforming technical commits into customer-friendly release notes.\",\n      \"source\": \"./changelog-generator\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"developer-growth-analysis\",\n      \"description\": \"Analyzes your recent Claude Code chat history to identify coding patterns, development gaps, and areas for improvement, curates relevant learning resources from HackerNews, and automatically sends a personalized growth report to your Slack DMs.\",\n      \"source\": \"./developer-growth-analysis\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"mcp-builder\",\n      \"description\": \"Guides creation of high-quality MCP (Model Context Protocol) servers for integrating external APIs and services with LLMs using Python or TypeScript.\",\n      \"source\": \"./mcp-builder\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"skill-creator\",\n      \"description\": \"Provides guidance for creating effective Claude Skills that extend capabilities with specialized knowledge, workflows, and tool integrations.\",\n      \"source\": \"./skill-creator\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"webapp-testing\",\n      \"description\": \"Tests local web applications using Playwright for verifying frontend functionality, debugging UI behavior, and capturing screenshots.\",\n      \"source\": \"./webapp-testing\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"template-skill\",\n      \"description\": \"A template skill that demonstrates the structure and format for creating new Claude Skills.\",\n      \"source\": \"./template-skill\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"file-organizer\",\n      \"description\": \"Intelligently organizes files and folders by understanding context, finding duplicates, and suggesting better organizational structures.\",\n      \"source\": \"./file-organizer\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"invoice-organizer\",\n      \"description\": \"Automatically organizes invoices and receipts for tax preparation by reading files, extracting information, and renaming consistently.\",\n      \"source\": \"./invoice-organizer\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"raffle-winner-picker\",\n      \"description\": \"Randomly selects winners from lists, spreadsheets, or Google Sheets for giveaways and contests with cryptographically secure randomness.\",\n      \"source\": \"./raffle-winner-picker\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"tailored-resume-generator\",\n      \"description\": \"Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances.\",\n      \"source\": \"./tailored-resume-generator\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"document-skills-docx\",\n      \"description\": \"Skills for working with Microsoft Word documents including creation, editing, and formatting using DOCX format.\",\n      \"source\": \"./document-skills/docx\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"document-skills-pdf\",\n      \"description\": \"Skills for working with PDF documents including creation, editing, forms, and advanced PDF operations.\",\n      \"source\": \"./document-skills/pdf\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"document-skills-pptx\",\n      \"description\": \"Skills for working with PowerPoint presentations including creation, editing, and formatting using PPTX format.\",\n      \"source\": \"./document-skills/pptx\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"document-skills-xlsx\",\n      \"description\": \"Skills for working with Excel spreadsheets including creation, editing, formulas, and data manipulation.\",\n      \"source\": \"./document-skills/xlsx\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"activecampaign-automation\",\n      \"description\": \"Automate ActiveCampaign tasks via Rube MCP (Composio): manage contacts, tags, list subscriptions, automation enrollment, and tasks.\",\n      \"source\": \"./activecampaign-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"airtable-automation\",\n      \"description\": \"Automate Airtable tasks via Rube MCP (Composio): records, bases, tables, fields, views.\",\n      \"source\": \"./airtable-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"amplitude-automation\",\n      \"description\": \"Automate Amplitude tasks via Rube MCP (Composio): events, user activity, cohorts, user identification.\",\n      \"source\": \"./amplitude-automation\",\n      \"category\": \"analytics\"\n    },\n    {\n      \"name\": \"asana-automation\",\n      \"description\": \"Automate Asana tasks via Rube MCP (Composio): tasks, projects, sections, teams, workspaces.\",\n      \"source\": \"./asana-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"bamboohr-automation\",\n      \"description\": \"Automate BambooHR tasks via Rube MCP (Composio): employees, time-off, benefits, dependents, employee updates.\",\n      \"source\": \"./bamboohr-automation\",\n      \"category\": \"hr\"\n    },\n    {\n      \"name\": \"basecamp-automation\",\n      \"description\": \"Automate Basecamp project management, to-dos, messages, people, and to-do list organization via Rube MCP (Composio).\",\n      \"source\": \"./basecamp-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"bitbucket-automation\",\n      \"description\": \"Automate Bitbucket repositories, pull requests, branches, issues, and workspace management via Rube MCP (Composio).\",\n      \"source\": \"./bitbucket-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"box-automation\",\n      \"description\": \"Automate Box cloud storage operations including file upload/download, search, folder management, sharing, collaborations, and metadata queries via Rube MCP (Composio).\",\n      \"source\": \"./box-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"brevo-automation\",\n      \"description\": \"Automate Brevo (Sendinblue) tasks via Rube MCP (Composio): manage email campaigns, create/edit templates, track senders, and monitor campaign performance.\",\n      \"source\": \"./brevo-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"cal-com-automation\",\n      \"description\": \"Automate Cal.com tasks via Rube MCP (Composio): manage bookings, check availability, configure webhooks, and handle teams.\",\n      \"source\": \"./cal-com-automation\",\n      \"category\": \"calendar\"\n    },\n    {\n      \"name\": \"calendly-automation\",\n      \"description\": \"Automate Calendly scheduling, event management, invitee tracking, availability checks, and organization administration via Rube MCP (Composio).\",\n      \"source\": \"./calendly-automation\",\n      \"category\": \"calendar\"\n    },\n    {\n      \"name\": \"canva-automation\",\n      \"description\": \"Automate Canva tasks via Rube MCP (Composio): designs, exports, folders, brand templates, autofill.\",\n      \"source\": \"./canva-automation\",\n      \"category\": \"design\"\n    },\n    {\n      \"name\": \"circleci-automation\",\n      \"description\": \"Automate CircleCI tasks via Rube MCP (Composio): trigger pipelines, monitor workflows/jobs, retrieve artifacts and test metadata.\",\n      \"source\": \"./circleci-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"clickup-automation\",\n      \"description\": \"Automate ClickUp project management including tasks, spaces, folders, lists, comments, and team operations via Rube MCP (Composio).\",\n      \"source\": \"./clickup-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"close-automation\",\n      \"description\": \"Automate Close CRM tasks via Rube MCP (Composio): create leads, manage calls/SMS, handle tasks, and track notes.\",\n      \"source\": \"./close-automation\",\n      \"category\": \"crm\"\n    },\n    {\n      \"name\": \"coda-automation\",\n      \"description\": \"Automate Coda tasks via Rube MCP (Composio): manage docs, pages, tables, rows, formulas, permissions, and publishing.\",\n      \"source\": \"./coda-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"confluence-automation\",\n      \"description\": \"Automate Confluence page creation, content search, space management, labels, and hierarchy navigation via Rube MCP (Composio).\",\n      \"source\": \"./confluence-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"convertkit-automation\",\n      \"description\": \"Automate ConvertKit (Kit) tasks via Rube MCP (Composio): manage subscribers, tags, broadcasts, and broadcast stats.\",\n      \"source\": \"./convertkit-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"datadog-automation\",\n      \"description\": \"Automate Datadog tasks via Rube MCP (Composio): query metrics, search logs, manage monitors/dashboards, create events and downtimes.\",\n      \"source\": \"./datadog-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"discord-automation\",\n      \"description\": \"Automate Discord tasks via Rube MCP (Composio): messages, channels, roles, webhooks, reactions.\",\n      \"source\": \"./discord-automation\",\n      \"category\": \"communication\"\n    },\n    {\n      \"name\": \"docusign-automation\",\n      \"description\": \"Automate DocuSign tasks via Rube MCP (Composio): templates, envelopes, signatures, document management.\",\n      \"source\": \"./docusign-automation\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"dropbox-automation\",\n      \"description\": \"Automate Dropbox file management, sharing, search, uploads, downloads, and folder operations via Rube MCP (Composio).\",\n      \"source\": \"./dropbox-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"figma-automation\",\n      \"description\": \"Automate Figma tasks via Rube MCP (Composio): files, components, design tokens, comments, exports.\",\n      \"source\": \"./figma-automation\",\n      \"category\": \"design\"\n    },\n    {\n      \"name\": \"freshdesk-automation\",\n      \"description\": \"Automate Freshdesk helpdesk operations including tickets, contacts, companies, notes, and replies via Rube MCP (Composio).\",\n      \"source\": \"./freshdesk-automation\",\n      \"category\": \"support\"\n    },\n    {\n      \"name\": \"freshservice-automation\",\n      \"description\": \"Automate Freshservice ITSM tasks via Rube MCP (Composio): create/update tickets, bulk operations, service requests, and outbound emails.\",\n      \"source\": \"./freshservice-automation\",\n      \"category\": \"support\"\n    },\n    {\n      \"name\": \"github-automation\",\n      \"description\": \"Automate GitHub repositories, issues, pull requests, branches, CI/CD, and permissions via Rube MCP (Composio). Manage code workflows, review PRs, search code, and handle deployments programmatically.\",\n      \"source\": \"./github-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"gitlab-automation\",\n      \"description\": \"Automate GitLab project management, issues, merge requests, pipelines, branches, and user operations via Rube MCP (Composio).\",\n      \"source\": \"./gitlab-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"gmail-automation\",\n      \"description\": \"Automate Gmail tasks via Rube MCP (Composio): send/reply, search, labels, drafts, attachments.\",\n      \"source\": \"./gmail-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"google-analytics-automation\",\n      \"description\": \"Automate Google Analytics tasks via Rube MCP (Composio): run reports, list accounts/properties, funnels, pivots, key events.\",\n      \"source\": \"./google-analytics-automation\",\n      \"category\": \"analytics\"\n    },\n    {\n      \"name\": \"google-calendar-automation\",\n      \"description\": \"Automate Google Calendar events, scheduling, availability checks, and attendee management via Rube MCP (Composio). Create events, find free slots, manage attendees, and list calendars programmatically.\",\n      \"source\": \"./google-calendar-automation\",\n      \"category\": \"calendar\"\n    },\n    {\n      \"name\": \"google-drive-automation\",\n      \"description\": \"Automate Google Drive file operations (upload, download, search, share, organize) via Rube MCP (Composio). Upload/download files, manage folders, share with permissions, and search across drives programmatically.\",\n      \"source\": \"./google-drive-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"googlesheets-automation\",\n      \"description\": \"Automate Google Sheets operations (read, write, format, filter, manage spreadsheets) via Rube MCP (Composio). Read/write data, manage tabs, apply formatting, and search rows programmatically.\",\n      \"source\": \"./googlesheets-automation\",\n      \"category\": \"spreadsheets\"\n    },\n    {\n      \"name\": \"helpdesk-automation\",\n      \"description\": \"Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields.\",\n      \"source\": \"./helpdesk-automation\",\n      \"category\": \"support\"\n    },\n    {\n      \"name\": \"hubspot-automation\",\n      \"description\": \"Automate HubSpot CRM operations (contacts, companies, deals, tickets, properties) via Rube MCP using Composio integration.\",\n      \"source\": \"./hubspot-automation\",\n      \"category\": \"crm\"\n    },\n    {\n      \"name\": \"instagram-automation\",\n      \"description\": \"Automate Instagram tasks via Rube MCP (Composio): create posts, carousels, manage media, get insights, and publishing limits.\",\n      \"source\": \"./instagram-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"intercom-automation\",\n      \"description\": \"Automate Intercom tasks via Rube MCP (Composio): conversations, contacts, companies, segments, admins.\",\n      \"source\": \"./intercom-automation\",\n      \"category\": \"support\"\n    },\n    {\n      \"name\": \"jira-automation\",\n      \"description\": \"Automate Jira tasks via Rube MCP (Composio): issues, projects, sprints, boards, comments, users.\",\n      \"source\": \"./jira-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"klaviyo-automation\",\n      \"description\": \"Automate Klaviyo tasks via Rube MCP (Composio): manage email/SMS campaigns, inspect campaign messages, track tags, and monitor send jobs.\",\n      \"source\": \"./klaviyo-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"linear-automation\",\n      \"description\": \"Automate Linear tasks via Rube MCP (Composio): issues, projects, cycles, teams, labels.\",\n      \"source\": \"./linear-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"linkedin-automation\",\n      \"description\": \"Automate LinkedIn tasks via Rube MCP (Composio): create posts, manage profile, company info, comments, and image uploads.\",\n      \"source\": \"./linkedin-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"mailchimp-automation\",\n      \"description\": \"Automate Mailchimp email marketing including campaigns, audiences, subscribers, segments, and analytics via Rube MCP (Composio).\",\n      \"source\": \"./mailchimp-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"make-automation\",\n      \"description\": \"Automate Make (Integromat) tasks via Rube MCP (Composio): operations, enums, language and timezone lookups.\",\n      \"source\": \"./make-automation\",\n      \"category\": \"automation\"\n    },\n    {\n      \"name\": \"microsoft-teams-automation\",\n      \"description\": \"Automate Microsoft Teams tasks via Rube MCP (Composio): send messages, manage channels, create meetings, handle chats, and search messages.\",\n      \"source\": \"./microsoft-teams-automation\",\n      \"category\": \"communication\"\n    },\n    {\n      \"name\": \"miro-automation\",\n      \"description\": \"Automate Miro tasks via Rube MCP (Composio): boards, items, sticky notes, frames, sharing, connectors.\",\n      \"source\": \"./miro-automation\",\n      \"category\": \"design\"\n    },\n    {\n      \"name\": \"mixpanel-automation\",\n      \"description\": \"Automate Mixpanel tasks via Rube MCP (Composio): events, segmentation, funnels, cohorts, user profiles, JQL queries.\",\n      \"source\": \"./mixpanel-automation\",\n      \"category\": \"analytics\"\n    },\n    {\n      \"name\": \"monday-automation\",\n      \"description\": \"Automate Monday.com work management including boards, items, columns, groups, subitems, and updates via Rube MCP (Composio).\",\n      \"source\": \"./monday-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"notion-automation\",\n      \"description\": \"Automate Notion tasks via Rube MCP (Composio): pages, databases, blocks, comments, users.\",\n      \"source\": \"./notion-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"one-drive-automation\",\n      \"description\": \"Automate OneDrive file management, search, uploads, downloads, sharing, permissions, and folder operations via Rube MCP (Composio).\",\n      \"source\": \"./one-drive-automation\",\n      \"category\": \"storage-docs\"\n    },\n    {\n      \"name\": \"outlook-automation\",\n      \"description\": \"Automate Outlook tasks via Rube MCP (Composio): emails, calendar, contacts, folders, attachments.\",\n      \"source\": \"./outlook-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"outlook-calendar-automation\",\n      \"description\": \"Automate Outlook Calendar tasks via Rube MCP (Composio): create events, manage attendees, find meeting times, and handle invitations.\",\n      \"source\": \"./outlook-calendar-automation\",\n      \"category\": \"calendar\"\n    },\n    {\n      \"name\": \"pagerduty-automation\",\n      \"description\": \"Automate PagerDuty tasks via Rube MCP (Composio): manage incidents, services, schedules, escalation policies, and on-call rotations.\",\n      \"source\": \"./pagerduty-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"pipedrive-automation\",\n      \"description\": \"Automate Pipedrive CRM operations including deals, contacts, organizations, activities, notes, and pipeline management via Rube MCP (Composio).\",\n      \"source\": \"./pipedrive-automation\",\n      \"category\": \"crm\"\n    },\n    {\n      \"name\": \"posthog-automation\",\n      \"description\": \"Automate PostHog tasks via Rube MCP (Composio): events, feature flags, projects, user profiles, annotations.\",\n      \"source\": \"./posthog-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"postmark-automation\",\n      \"description\": \"Automate Postmark email delivery tasks via Rube MCP (Composio): send templated emails, manage templates, monitor delivery stats and bounces.\",\n      \"source\": \"./postmark-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"reddit-automation\",\n      \"description\": \"Automate Reddit tasks via Rube MCP (Composio): search subreddits, create posts, manage comments, and browse top content.\",\n      \"source\": \"./reddit-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"render-automation\",\n      \"description\": \"Automate Render tasks via Rube MCP (Composio): services, deployments, projects.\",\n      \"source\": \"./render-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"salesforce-automation\",\n      \"description\": \"Automate Salesforce tasks via Rube MCP (Composio): leads, contacts, accounts, opportunities, SOQL queries.\",\n      \"source\": \"./salesforce-automation\",\n      \"category\": \"crm\"\n    },\n    {\n      \"name\": \"segment-automation\",\n      \"description\": \"Automate Segment tasks via Rube MCP (Composio): track events, identify users, manage groups, page views, aliases, batch operations.\",\n      \"source\": \"./segment-automation\",\n      \"category\": \"analytics\"\n    },\n    {\n      \"name\": \"sendgrid-automation\",\n      \"description\": \"Automate SendGrid email operations including sending emails, managing contacts/lists, sender identities, templates, and analytics via Rube MCP (Composio).\",\n      \"source\": \"./sendgrid-automation\",\n      \"category\": \"email\"\n    },\n    {\n      \"name\": \"sentry-automation\",\n      \"description\": \"Automate Sentry tasks via Rube MCP (Composio): manage issues/events, configure alerts, track releases, monitor projects and teams.\",\n      \"source\": \"./sentry-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"shopify-automation\",\n      \"description\": \"Automate Shopify tasks via Rube MCP (Composio): products, orders, customers, inventory, collections.\",\n      \"source\": \"./shopify-automation\",\n      \"category\": \"ecommerce\"\n    },\n    {\n      \"name\": \"slack-automation\",\n      \"description\": \"Automate Slack messaging, channel management, search, reactions, and threads via Rube MCP (Composio). Send messages, search conversations, manage channels/users, and react to messages programmatically.\",\n      \"source\": \"./slack-automation\",\n      \"category\": \"communication\"\n    },\n    {\n      \"name\": \"square-automation\",\n      \"description\": \"Automate Square tasks via Rube MCP (Composio): payments, orders, invoices, locations.\",\n      \"source\": \"./square-automation\",\n      \"category\": \"ecommerce\"\n    },\n    {\n      \"name\": \"stripe-automation\",\n      \"description\": \"Automate Stripe tasks via Rube MCP (Composio): customers, charges, subscriptions, invoices, products, refunds.\",\n      \"source\": \"./stripe-automation\",\n      \"category\": \"ecommerce\"\n    },\n    {\n      \"name\": \"supabase-automation\",\n      \"description\": \"Automate Supabase database queries, table management, project administration, storage, edge functions, and SQL execution via Rube MCP (Composio).\",\n      \"source\": \"./supabase-automation\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"telegram-automation\",\n      \"description\": \"Automate Telegram tasks via Rube MCP (Composio): send messages, manage chats, share photos/documents, and handle bot commands.\",\n      \"source\": \"./telegram-automation\",\n      \"category\": \"communication\"\n    },\n    {\n      \"name\": \"tiktok-automation\",\n      \"description\": \"Automate TikTok tasks via Rube MCP (Composio): upload/publish videos, post photos, manage content, and view user profiles/stats.\",\n      \"source\": \"./tiktok-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"todoist-automation\",\n      \"description\": \"Automate Todoist task management, projects, sections, filtering, and bulk operations via Rube MCP (Composio).\",\n      \"source\": \"./todoist-automation\",\n      \"category\": \"productivity-organization\"\n    },\n    {\n      \"name\": \"trello-automation\",\n      \"description\": \"Automate Trello boards, cards, and workflows via Rube MCP (Composio). Create cards, manage lists, assign members, and search across boards programmatically.\",\n      \"source\": \"./trello-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"twitter-automation\",\n      \"description\": \"Automate Twitter/X tasks via Rube MCP (Composio): posts, search, users, bookmarks, lists, media.\",\n      \"source\": \"./twitter-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"vercel-automation\",\n      \"description\": \"Automate Vercel tasks via Rube MCP (Composio): manage deployments, domains, DNS, env vars, projects, and teams.\",\n      \"source\": \"./vercel-automation\",\n      \"category\": \"devops\"\n    },\n    {\n      \"name\": \"webflow-automation\",\n      \"description\": \"Automate Webflow CMS collections, site publishing, page management, asset uploads, and ecommerce orders via Rube MCP (Composio).\",\n      \"source\": \"./webflow-automation\",\n      \"category\": \"development\"\n    },\n    {\n      \"name\": \"whatsapp-automation\",\n      \"description\": \"Automate WhatsApp Business tasks via Rube MCP (Composio): send messages, manage templates, upload media, and handle contacts.\",\n      \"source\": \"./whatsapp-automation\",\n      \"category\": \"communication\"\n    },\n    {\n      \"name\": \"wrike-automation\",\n      \"description\": \"Automate Wrike project management via Rube MCP (Composio): create tasks/folders, manage projects, assign work, and track progress.\",\n      \"source\": \"./wrike-automation\",\n      \"category\": \"project-management\"\n    },\n    {\n      \"name\": \"youtube-automation\",\n      \"description\": \"Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments.\",\n      \"source\": \"./youtube-automation\",\n      \"category\": \"social-media\"\n    },\n    {\n      \"name\": \"zendesk-automation\",\n      \"description\": \"Automate Zendesk tasks via Rube MCP (Composio): tickets, users, organizations, replies.\",\n      \"source\": \"./zendesk-automation\",\n      \"category\": \"support\"\n    },\n    {\n      \"name\": \"zoho-crm-automation\",\n      \"description\": \"Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads.\",\n      \"source\": \"./zoho-crm-automation\",\n      \"category\": \"crm\"\n    },\n    {\n      \"name\": \"zoom-automation\",\n      \"description\": \"Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio).\",\n      \"source\": \"./zoom-automation\",\n      \"category\": \"automation\"\n    }\n  ]\n}"
  },
  {
    "path": "composio-skills/ably-automation/SKILL.md",
    "content": "---\nname: ably-automation\ndescription: \"Automate Ably tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ably Automation via Rube MCP\n\nAutomate Ably operations through Composio's Ably toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ably](https://composio.dev/toolkits/ably)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ably connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ably`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ably`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ably operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ably task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ably\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ably-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ably` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/abstract-automation/SKILL.md",
    "content": "---\nname: abstract-automation\ndescription: \"Automate Abstract tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Abstract Automation via Rube MCP\n\nAutomate Abstract operations through Composio's Abstract toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/abstract](https://composio.dev/toolkits/abstract)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Abstract connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `abstract`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `abstract`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Abstract operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Abstract task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"abstract\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Abstract-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `abstract` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/abuselpdb-automation/SKILL.md",
    "content": "---\nname: abuselpdb-automation\ndescription: \"Automate Abuselpdb tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Abuselpdb Automation via Rube MCP\n\nAutomate Abuselpdb operations through Composio's Abuselpdb toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/abuselpdb](https://composio.dev/toolkits/abuselpdb)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Abuselpdb connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `abuselpdb`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `abuselpdb`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Abuselpdb operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Abuselpdb task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"abuselpdb\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Abuselpdb-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `abuselpdb` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/abyssale-automation/SKILL.md",
    "content": "---\nname: abyssale-automation\ndescription: \"Automate Abyssale tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Abyssale Automation via Rube MCP\n\nAutomate Abyssale operations through Composio's Abyssale toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/abyssale](https://composio.dev/toolkits/abyssale)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Abyssale connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `abyssale`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `abyssale`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Abyssale operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Abyssale task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"abyssale\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Abyssale-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `abyssale` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/accelo-automation/SKILL.md",
    "content": "---\nname: accelo-automation\ndescription: \"Automate Accelo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Accelo Automation via Rube MCP\n\nAutomate Accelo operations through Composio's Accelo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/accelo](https://composio.dev/toolkits/accelo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Accelo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `accelo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `accelo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Accelo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Accelo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"accelo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Accelo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `accelo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/accredible-certificates-automation/SKILL.md",
    "content": "---\nname: accredible-certificates-automation\ndescription: \"Automate Accredible Certificates tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Accredible Certificates Automation via Rube MCP\n\nAutomate Accredible Certificates operations through Composio's Accredible Certificates toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/accredible_certificates](https://composio.dev/toolkits/accredible_certificates)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Accredible Certificates connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `accredible_certificates`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `accredible_certificates`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Accredible Certificates operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Accredible Certificates task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"accredible_certificates\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Accredible Certificates-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `accredible_certificates` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/acculynx-automation/SKILL.md",
    "content": "---\nname: acculynx-automation\ndescription: \"Automate Acculynx tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Acculynx Automation via Rube MCP\n\nAutomate Acculynx operations through Composio's Acculynx toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/acculynx](https://composio.dev/toolkits/acculynx)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Acculynx connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `acculynx`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `acculynx`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Acculynx operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Acculynx task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"acculynx\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Acculynx-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `acculynx` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/active-campaign-automation/SKILL.md",
    "content": "---\nname: active-campaign-automation\ndescription: \"Automate ActiveCampaign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# ActiveCampaign Automation via Rube MCP\n\nAutomate ActiveCampaign operations through Composio's ActiveCampaign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/active_campaign](https://composio.dev/toolkits/active_campaign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active ActiveCampaign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `active_campaign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `active_campaign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"ActiveCampaign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific ActiveCampaign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"active_campaign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with ActiveCampaign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `active_campaign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/addresszen-automation/SKILL.md",
    "content": "---\nname: addresszen-automation\ndescription: \"Automate Addresszen tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Addresszen Automation via Rube MCP\n\nAutomate Addresszen operations through Composio's Addresszen toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/addresszen](https://composio.dev/toolkits/addresszen)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Addresszen connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `addresszen`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `addresszen`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Addresszen operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Addresszen task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"addresszen\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Addresszen-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `addresszen` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/adobe-automation/SKILL.md",
    "content": "---\nname: adobe-automation\ndescription: \"Automate Adobe tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Adobe Automation via Rube MCP\n\nAutomate Adobe operations through Composio's Adobe toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/adobe](https://composio.dev/toolkits/adobe)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Adobe connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `adobe`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `adobe`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Adobe operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Adobe task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"adobe\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Adobe-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `adobe` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/adrapid-automation/SKILL.md",
    "content": "---\nname: adrapid-automation\ndescription: \"Automate Adrapid tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Adrapid Automation via Rube MCP\n\nAutomate Adrapid operations through Composio's Adrapid toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/adrapid](https://composio.dev/toolkits/adrapid)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Adrapid connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `adrapid`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `adrapid`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Adrapid operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Adrapid task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"adrapid\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Adrapid-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `adrapid` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/adyntel-automation/SKILL.md",
    "content": "---\nname: adyntel-automation\ndescription: \"Automate Adyntel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Adyntel Automation via Rube MCP\n\nAutomate Adyntel operations through Composio's Adyntel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/adyntel](https://composio.dev/toolkits/adyntel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Adyntel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `adyntel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `adyntel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Adyntel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Adyntel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"adyntel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Adyntel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `adyntel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/aero-workflow-automation/SKILL.md",
    "content": "---\nname: aero-workflow-automation\ndescription: \"Automate Aero Workflow tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Aero Workflow Automation via Rube MCP\n\nAutomate Aero Workflow operations through Composio's Aero Workflow toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/aero_workflow](https://composio.dev/toolkits/aero_workflow)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Aero Workflow connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `aero_workflow`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `aero_workflow`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Aero Workflow operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Aero Workflow task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"aero_workflow\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Aero Workflow-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `aero_workflow` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/aeroleads-automation/SKILL.md",
    "content": "---\nname: aeroleads-automation\ndescription: \"Automate Aeroleads tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Aeroleads Automation via Rube MCP\n\nAutomate Aeroleads operations through Composio's Aeroleads toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/aeroleads](https://composio.dev/toolkits/aeroleads)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Aeroleads connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `aeroleads`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `aeroleads`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Aeroleads operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Aeroleads task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"aeroleads\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Aeroleads-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `aeroleads` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/affinda-automation/SKILL.md",
    "content": "---\nname: affinda-automation\ndescription: \"Automate Affinda tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Affinda Automation via Rube MCP\n\nAutomate Affinda operations through Composio's Affinda toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/affinda](https://composio.dev/toolkits/affinda)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Affinda connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `affinda`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `affinda`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Affinda operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Affinda task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"affinda\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Affinda-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `affinda` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/affinity-automation/SKILL.md",
    "content": "---\nname: affinity-automation\ndescription: \"Automate Affinity tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Affinity Automation via Rube MCP\n\nAutomate Affinity operations through Composio's Affinity toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/affinity](https://composio.dev/toolkits/affinity)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Affinity connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `affinity`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `affinity`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Affinity operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Affinity task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"affinity\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Affinity-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `affinity` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agencyzoom-automation/SKILL.md",
    "content": "---\nname: agencyzoom-automation\ndescription: \"Automate Agencyzoom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agencyzoom Automation via Rube MCP\n\nAutomate Agencyzoom operations through Composio's Agencyzoom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agencyzoom](https://composio.dev/toolkits/agencyzoom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agencyzoom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agencyzoom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agencyzoom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agencyzoom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agencyzoom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agencyzoom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agencyzoom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agencyzoom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agent-mail-automation/SKILL.md",
    "content": "---\nname: agent-mail-automation\ndescription: \"Automate Agent Mail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agent Mail Automation via Rube MCP\n\nAutomate Agent Mail operations through Composio's Agent Mail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agent_mail](https://composio.dev/toolkits/agent_mail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agent Mail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agent_mail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agent_mail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agent Mail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agent Mail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agent_mail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agent Mail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agent_mail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agentql-automation/SKILL.md",
    "content": "---\nname: agentql-automation\ndescription: \"Automate Agentql tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agentql Automation via Rube MCP\n\nAutomate Agentql operations through Composio's Agentql toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agentql](https://composio.dev/toolkits/agentql)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agentql connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agentql`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agentql`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agentql operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agentql task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agentql\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agentql-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agentql` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agenty-automation/SKILL.md",
    "content": "---\nname: agenty-automation\ndescription: \"Automate Agenty tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agenty Automation via Rube MCP\n\nAutomate Agenty operations through Composio's Agenty toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agenty](https://composio.dev/toolkits/agenty)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agenty connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agenty`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agenty`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agenty operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agenty task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agenty\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agenty-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agenty` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agiled-automation/SKILL.md",
    "content": "---\nname: agiled-automation\ndescription: \"Automate Agiled tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agiled Automation via Rube MCP\n\nAutomate Agiled operations through Composio's Agiled toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agiled](https://composio.dev/toolkits/agiled)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agiled connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agiled`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agiled`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agiled operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agiled task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agiled\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agiled-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agiled` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/agility-cms-automation/SKILL.md",
    "content": "---\nname: agility-cms-automation\ndescription: \"Automate Agility CMS tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Agility CMS Automation via Rube MCP\n\nAutomate Agility CMS operations through Composio's Agility CMS toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/agility_cms](https://composio.dev/toolkits/agility_cms)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Agility CMS connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `agility_cms`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `agility_cms`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Agility CMS operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Agility CMS task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"agility_cms\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Agility CMS-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `agility_cms` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ahrefs-automation/SKILL.md",
    "content": "---\nname: Ahrefs Automation\ndescription: \"Automate SEO research with Ahrefs -- analyze backlink profiles, research keywords, track domain metrics history, audit organic rankings, and perform batch URL analysis through the Composio Ahrefs integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Ahrefs Automation\n\nRun **Ahrefs** SEO analytics directly from Claude Code. Analyze backlink profiles, research keywords, track domain authority over time, audit organic keyword rankings, and batch-analyze multiple URLs without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/ahrefs](https://composio.dev/toolkits/ahrefs)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Ahrefs account when prompted. The agent will provide an authentication link.\n3. Most tools require a `target` (domain or URL) and a `country` code (ISO 3166-1 alpha-2). Some also require a `date` in `YYYY-MM-DD` format.\n\n---\n\n## Core Workflows\n\n### 1. Site Explorer Metrics\n\nRetrieve comprehensive SEO metrics for a domain including backlink counts, referring domains, organic keyword rankings, and traffic estimates.\n\n**Tool:** `AHREFS_RETRIEVE_SITE_EXPLORER_METRICS`\n\nKey parameters:\n- `target` (required) -- domain or URL to analyze\n- `date` (required) -- metrics date in `YYYY-MM-DD` format\n- `country` -- ISO country code (e.g., `us`, `gb`, `de`)\n- `mode` -- scope: `exact`, `prefix`, `domain`, or `subdomains` (default)\n- `protocol` -- `both`, `http`, or `https`\n- `volume_mode` -- `monthly` or `average`\n\nExample prompt: *\"Get Ahrefs site metrics for example.com as of today in the US\"*\n\n---\n\n### 2. Historical Metrics Tracking\n\nTrack how a domain's SEO metrics have changed over time for trend analysis and competitive benchmarking.\n\n**Tools:** `AHREFS_RETRIEVE_SITE_EXPLORER_METRICS_HISTORY`, `AHREFS_DOMAIN_RATING_HISTORY`\n\nFor full metrics history:\n- `target` (required) -- domain to track\n- `date_from` (required) -- start date in `YYYY-MM-DD`\n- `date_to` -- end date\n- `history_grouping` -- `daily`, `weekly`, or `monthly` (default)\n- `select` -- columns like `date,org_cost,org_traffic,paid_cost,paid_traffic`\n\nFor Domain Rating (DR) history:\n- `target` (required), `date_from` (required), `date_to`, `history_grouping`\n\nExample prompt: *\"Show me the monthly Domain Rating history for example.com over the last year\"*\n\n---\n\n### 3. Backlink Analysis\n\nRetrieve a comprehensive list of backlinks including source URLs, anchor text, link attributes, and referring domain metrics.\n\n**Tool:** `AHREFS_FETCH_ALL_BACKLINKS`\n\nKey parameters:\n- `target` (required) -- domain or URL\n- `select` (required) -- comma-separated columns (e.g., `url_from,url_to,anchor,domain_rating_source,first_seen_link`)\n- `limit` (default 1000) -- number of results\n- `aggregation` -- `similar_links` (default), `1_per_domain`, or `all`\n- `mode` -- `exact`, `prefix`, `domain`, or `subdomains`\n- `history` -- `live`, `since:YYYY-MM-DD`, or `all_time`\n- `where` -- rich filter expressions on columns like `is_dofollow`, `domain_rating_source`, `anchor`\n\nExample prompt: *\"Get the top 100 dofollow backlinks to example.com with anchor text and referring DR\"*\n\n---\n\n### 4. Keyword Research\n\nGet keyword overview metrics and discover matching keyword variations for content strategy.\n\n**Tools:** `AHREFS_EXPLORE_KEYWORDS_OVERVIEW`, `AHREFS_EXPLORE_MATCHING_TERMS_FOR_KEYWORDS`\n\nFor keyword overview:\n- `select` (required) -- columns to return (volume, difficulty, CPC, etc.)\n- `country` (required) -- ISO country code\n- `keywords` -- comma-separated keyword list\n- `where` -- filter by volume, difficulty, intent, etc.\n\nFor matching terms:\n- `select` (required) and `country` (required)\n- `keywords` -- comma-separated seed keywords\n- `match_mode` -- `terms` (any order) or `phrase` (exact order)\n- `terms` -- `all` or `questions` (question-format keywords only)\n\nExample prompt: *\"Find keyword variations for 'project management' in the US with volume and difficulty\"*\n\n---\n\n### 5. Organic Keywords Audit\n\nSee which keywords a domain ranks for in organic search, with position tracking and historical comparison.\n\n**Tool:** `AHREFS_RETRIEVE_ORGANIC_KEYWORDS`\n\nKey parameters:\n- `target` (required) -- domain or URL\n- `country` (required) -- ISO country code\n- `date` (required) -- date in `YYYY-MM-DD`\n- `select` -- columns to return (keyword, position, volume, traffic, URL, etc.)\n- `date_compared` -- compare against a previous date\n- `where` -- rich filter expressions on `keyword`, `volume`, `best_position`, intent flags, etc.\n- `limit` (default 1000), `order_by`\n\nExample prompt: *\"Show all organic keywords where example.com ranks in the top 10 in the US\"*\n\n---\n\n### 6. Batch URL Analysis\n\nAnalyze up to 100 URLs or domains simultaneously to compare SEO metrics across competitors or site sections.\n\n**Tool:** `AHREFS_BATCH_URL_ANALYSIS`\n\nKey parameters:\n- `targets` (required) -- array of objects with `url`, `mode` (`exact`/`prefix`/`domain`/`subdomains`), and `protocol` (`both`/`http`/`https`)\n- `select` (required) -- array of column identifiers\n- `country` -- ISO country code\n- `output` -- `json` or `php`\n\nExample prompt: *\"Compare SEO metrics for competitor1.com, competitor2.com, and competitor3.com\"*\n\n---\n\n## Known Pitfalls\n\n- **Column selection is required:** Most Ahrefs tools require a `select` parameter specifying which columns to return. Omitting it or using invalid column names will cause errors. Refer to each tool's response schema for valid identifiers.\n- **Date format consistency:** Dates must be in `YYYY-MM-DD` format. Some historical endpoints return data at the granularity set by `history_grouping`, not by exact date.\n- **API unit costs vary:** Different columns consume different unit amounts. Columns marked with \"(5 units)\" or \"(10 units)\" in the schema are more expensive. Monitor API usage when requesting expensive columns like `traffic`, `refdomains_source`, or `difficulty`.\n- **Batch limit is 100 targets:** `AHREFS_BATCH_URL_ANALYSIS` accepts up to 100 targets per request. For larger analyses, split into multiple batches.\n- **Filter expressions are complex:** The `where` parameter uses Ahrefs' filter expression syntax, not standard SQL. Consult the column descriptions in each tool's schema for supported filter types and value formats.\n- **Deprecated offset parameter:** The `offset` parameter was deprecated on May 31, 2024. Use cursor-based pagination or adjust `limit` instead.\n- **Mode affects scope significantly:** Setting `mode` to `subdomains` (the default) includes all subdomains, which can dramatically increase result counts compared to `domain` or `exact`.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `AHREFS_RETRIEVE_SITE_EXPLORER_METRICS` | Current SEO metrics for a domain/URL |\n| `AHREFS_RETRIEVE_SITE_EXPLORER_METRICS_HISTORY` | Historical SEO metrics over time |\n| `AHREFS_DOMAIN_RATING_HISTORY` | Domain Rating (DR) history |\n| `AHREFS_FETCH_ALL_BACKLINKS` | Comprehensive backlink list with filtering |\n| `AHREFS_FETCH_SITE_EXPLORER_REFERRING_DOMAINS` | List of referring domains |\n| `AHREFS_GET_SITE_EXPLORER_COUNTRY_METRICS` | Country-level traffic breakdown |\n| `AHREFS_BATCH_URL_ANALYSIS` | Batch analysis of up to 100 URLs |\n| `AHREFS_EXPLORE_KEYWORDS_OVERVIEW` | Keyword metrics overview |\n| `AHREFS_EXPLORE_MATCHING_TERMS_FOR_KEYWORDS` | Matching keyword variations |\n| `AHREFS_EXPLORE_KEYWORD_VOLUME_BY_COUNTRY` | Keyword volume across countries |\n| `AHREFS_RETRIEVE_ORGANIC_KEYWORDS` | Organic keyword rankings for a domain |\n| `AHREFS_RETRIEVE_SITE_EXPLORER_KEYWORDS_HISTORY` | Historical keyword ranking data |\n| `AHREFS_RETRIEVE_TOP_PAGES_FROM_SITE_EXPLORER` | Top performing pages by SEO metrics |\n| `AHREFS_GET_SERP_OVERVIEW` | SERP overview for specific keywords |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ai-ml-api-automation/SKILL.md",
    "content": "---\nname: ai-ml-api-automation\ndescription: \"Automate AI ML API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# AI ML API Automation via Rube MCP\n\nAutomate AI ML API operations through Composio's AI ML API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ai_ml_api](https://composio.dev/toolkits/ai_ml_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active AI ML API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ai_ml_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ai_ml_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"AI ML API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific AI ML API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ai_ml_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with AI ML API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ai_ml_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/aivoov-automation/SKILL.md",
    "content": "---\nname: aivoov-automation\ndescription: \"Automate Aivoov tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Aivoov Automation via Rube MCP\n\nAutomate Aivoov operations through Composio's Aivoov toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/aivoov](https://composio.dev/toolkits/aivoov)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Aivoov connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `aivoov`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `aivoov`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Aivoov operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Aivoov task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"aivoov\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Aivoov-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `aivoov` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/alchemy-automation/SKILL.md",
    "content": "---\nname: alchemy-automation\ndescription: \"Automate Alchemy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Alchemy Automation via Rube MCP\n\nAutomate Alchemy operations through Composio's Alchemy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/alchemy](https://composio.dev/toolkits/alchemy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Alchemy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `alchemy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `alchemy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Alchemy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Alchemy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"alchemy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Alchemy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `alchemy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/algodocs-automation/SKILL.md",
    "content": "---\nname: algodocs-automation\ndescription: \"Automate Algodocs tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Algodocs Automation via Rube MCP\n\nAutomate Algodocs operations through Composio's Algodocs toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/algodocs](https://composio.dev/toolkits/algodocs)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Algodocs connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `algodocs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `algodocs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Algodocs operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Algodocs task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"algodocs\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Algodocs-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `algodocs` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/algolia-automation/SKILL.md",
    "content": "---\nname: algolia-automation\ndescription: \"Automate Algolia tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Algolia Automation via Rube MCP\n\nAutomate Algolia operations through Composio's Algolia toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/algolia](https://composio.dev/toolkits/algolia)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Algolia connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `algolia`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `algolia`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Algolia operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Algolia task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"algolia\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Algolia-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `algolia` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/all-images-ai-automation/SKILL.md",
    "content": "---\nname: all-images-ai-automation\ndescription: \"Automate All Images AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# All Images AI Automation via Rube MCP\n\nAutomate All Images AI operations through Composio's All Images AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/all_images_ai](https://composio.dev/toolkits/all_images_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active All Images AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `all_images_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `all_images_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"All Images AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific All Images AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"all_images_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with All Images AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `all_images_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/alpha-vantage-automation/SKILL.md",
    "content": "---\nname: alpha-vantage-automation\ndescription: \"Automate Alpha Vantage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Alpha Vantage Automation via Rube MCP\n\nAutomate Alpha Vantage operations through Composio's Alpha Vantage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/alpha_vantage](https://composio.dev/toolkits/alpha_vantage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Alpha Vantage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `alpha_vantage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `alpha_vantage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Alpha Vantage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Alpha Vantage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"alpha_vantage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Alpha Vantage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `alpha_vantage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/altoviz-automation/SKILL.md",
    "content": "---\nname: altoviz-automation\ndescription: \"Automate Altoviz tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Altoviz Automation via Rube MCP\n\nAutomate Altoviz operations through Composio's Altoviz toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/altoviz](https://composio.dev/toolkits/altoviz)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Altoviz connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `altoviz`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `altoviz`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Altoviz operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Altoviz task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"altoviz\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Altoviz-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `altoviz` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/alttext-ai-automation/SKILL.md",
    "content": "---\nname: alttext-ai-automation\ndescription: \"Automate Alttext AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Alttext AI Automation via Rube MCP\n\nAutomate Alttext AI operations through Composio's Alttext AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/alttext_ai](https://composio.dev/toolkits/alttext_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Alttext AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `alttext_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `alttext_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Alttext AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Alttext AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"alttext_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Alttext AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `alttext_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/amara-automation/SKILL.md",
    "content": "---\nname: amara-automation\ndescription: \"Automate Amara tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Amara Automation via Rube MCP\n\nAutomate Amara operations through Composio's Amara toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/amara](https://composio.dev/toolkits/amara)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Amara connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `amara`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `amara`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Amara operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Amara task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"amara\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Amara-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `amara` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/amazon-automation/SKILL.md",
    "content": "---\nname: amazon-automation\ndescription: \"Automate Amazon tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Amazon Automation via Rube MCP\n\nAutomate Amazon operations through Composio's Amazon toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/amazon](https://composio.dev/toolkits/amazon)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Amazon connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `amazon`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `amazon`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Amazon operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Amazon task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"amazon\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Amazon-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `amazon` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ambee-automation/SKILL.md",
    "content": "---\nname: ambee-automation\ndescription: \"Automate Ambee tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ambee Automation via Rube MCP\n\nAutomate Ambee operations through Composio's Ambee toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ambee](https://composio.dev/toolkits/ambee)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ambee connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ambee`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ambee`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ambee operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ambee task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ambee\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ambee-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ambee` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ambient-weather-automation/SKILL.md",
    "content": "---\nname: ambient-weather-automation\ndescription: \"Automate Ambient Weather tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ambient Weather Automation via Rube MCP\n\nAutomate Ambient Weather operations through Composio's Ambient Weather toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ambient_weather](https://composio.dev/toolkits/ambient_weather)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ambient Weather connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ambient_weather`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ambient_weather`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ambient Weather operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ambient Weather task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ambient_weather\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ambient Weather-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ambient_weather` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/amcards-automation/SKILL.md",
    "content": "---\nname: amcards-automation\ndescription: \"Automate Amcards tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Amcards Automation via Rube MCP\n\nAutomate Amcards operations through Composio's Amcards toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/amcards](https://composio.dev/toolkits/amcards)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Amcards connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `amcards`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `amcards`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Amcards operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Amcards task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"amcards\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Amcards-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `amcards` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/anchor-browser-automation/SKILL.md",
    "content": "---\nname: anchor-browser-automation\ndescription: \"Automate Anchor Browser tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Anchor Browser Automation via Rube MCP\n\nAutomate Anchor Browser operations through Composio's Anchor Browser toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/anchor_browser](https://composio.dev/toolkits/anchor_browser)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Anchor Browser connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `anchor_browser`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `anchor_browser`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Anchor Browser operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Anchor Browser task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"anchor_browser\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Anchor Browser-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `anchor_browser` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/anonyflow-automation/SKILL.md",
    "content": "---\nname: anonyflow-automation\ndescription: \"Automate Anonyflow tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Anonyflow Automation via Rube MCP\n\nAutomate Anonyflow operations through Composio's Anonyflow toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/anonyflow](https://composio.dev/toolkits/anonyflow)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Anonyflow connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `anonyflow`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `anonyflow`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Anonyflow operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Anonyflow task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"anonyflow\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Anonyflow-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `anonyflow` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/anthropic-administrator-automation/SKILL.md",
    "content": "---\nname: anthropic-administrator-automation\ndescription: \"Automate Anthropic Admin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Anthropic Admin Automation via Rube MCP\n\nAutomate Anthropic Admin operations through Composio's Anthropic Admin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/anthropic_administrator](https://composio.dev/toolkits/anthropic_administrator)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Anthropic Admin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Anthropic Admin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Anthropic Admin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"anthropic_administrator\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Anthropic Admin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/anthropic_administrator-automation/SKILL.md",
    "content": "---\nname: anthropic_administrator-automation\ndescription: \"Automate Anthropic Admin tasks via Rube MCP (Composio): API keys, usage, workspaces, and organization management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Anthropic Admin Automation via Rube MCP\n\nAutomate Anthropic Admin operations through Composio's Anthropic Admin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/anthropic_administrator](https://composio.dev/toolkits/anthropic_administrator)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Anthropic Admin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"API keys, usage, workspaces, and organization management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Anthropic Admin\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Anthropic Admin Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Anthropic Admin tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Anthropic Admin Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Anthropic Admin operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Anthropic Admin connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Anthropic Admin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `anthropic_administrator` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/anthropic_administrator](https://composio.dev/toolkits/anthropic_administrator)\n"
  },
  {
    "path": "composio-skills/apaleo-automation/SKILL.md",
    "content": "---\nname: apaleo-automation\ndescription: \"Automate Apaleo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apaleo Automation via Rube MCP\n\nAutomate Apaleo operations through Composio's Apaleo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apaleo](https://composio.dev/toolkits/apaleo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apaleo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apaleo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apaleo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apaleo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apaleo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apaleo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apaleo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apaleo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apex27-automation/SKILL.md",
    "content": "---\nname: apex27-automation\ndescription: \"Automate Apex27 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apex27 Automation via Rube MCP\n\nAutomate Apex27 operations through Composio's Apex27 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apex27](https://composio.dev/toolkits/apex27)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apex27 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apex27`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apex27`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apex27 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apex27 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apex27\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apex27-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apex27` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/api-bible-automation/SKILL.md",
    "content": "---\nname: api-bible-automation\ndescription: \"Automate API Bible tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# API Bible Automation via Rube MCP\n\nAutomate API Bible operations through Composio's API Bible toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/api_bible](https://composio.dev/toolkits/api_bible)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active API Bible connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `api_bible`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `api_bible`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"API Bible operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific API Bible task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"api_bible\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with API Bible-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `api_bible` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/api-labz-automation/SKILL.md",
    "content": "---\nname: api-labz-automation\ndescription: \"Automate API Labz tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# API Labz Automation via Rube MCP\n\nAutomate API Labz operations through Composio's API Labz toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/api_labz](https://composio.dev/toolkits/api_labz)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active API Labz connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `api_labz`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `api_labz`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"API Labz operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific API Labz task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"api_labz\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with API Labz-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `api_labz` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/api-ninjas-automation/SKILL.md",
    "content": "---\nname: api-ninjas-automation\ndescription: \"Automate API Ninjas tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# API Ninjas Automation via Rube MCP\n\nAutomate API Ninjas operations through Composio's API Ninjas toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/api_ninjas](https://composio.dev/toolkits/api_ninjas)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active API Ninjas connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `api_ninjas`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `api_ninjas`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"API Ninjas operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific API Ninjas task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"api_ninjas\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with API Ninjas-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `api_ninjas` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/api-sports-automation/SKILL.md",
    "content": "---\nname: api-sports-automation\ndescription: \"Automate API Sports tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# API Sports Automation via Rube MCP\n\nAutomate API Sports operations through Composio's API Sports toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/api_sports](https://composio.dev/toolkits/api_sports)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active API Sports connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `api_sports`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `api_sports`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"API Sports operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific API Sports task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"api_sports\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with API Sports-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `api_sports` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/api2pdf-automation/SKILL.md",
    "content": "---\nname: api2pdf-automation\ndescription: \"Automate Api2pdf tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Api2pdf Automation via Rube MCP\n\nAutomate Api2pdf operations through Composio's Api2pdf toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/api2pdf](https://composio.dev/toolkits/api2pdf)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Api2pdf connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `api2pdf`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `api2pdf`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Api2pdf operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Api2pdf task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"api2pdf\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Api2pdf-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `api2pdf` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apiflash-automation/SKILL.md",
    "content": "---\nname: apiflash-automation\ndescription: \"Automate Apiflash tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apiflash Automation via Rube MCP\n\nAutomate Apiflash operations through Composio's Apiflash toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apiflash](https://composio.dev/toolkits/apiflash)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apiflash connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apiflash`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apiflash`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apiflash operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apiflash task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apiflash\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apiflash-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apiflash` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apify-automation/SKILL.md",
    "content": "---\nname: Apify Automation\ndescription: \"Automate web scraping and data extraction with Apify -- run Actors, manage datasets, create reusable tasks, and retrieve crawl results through the Composio Apify integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Apify Automation\n\nRun **Apify** web scraping Actors and manage datasets directly from Claude Code. Execute crawlers synchronously or asynchronously, retrieve structured data, create reusable tasks, and inspect run logs without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/apify](https://composio.dev/toolkits/apify)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Apify account when prompted. The agent will provide an authentication link.\n3. Browse available Actors at [apify.com/store](https://apify.com/store). Each Actor has its own unique input schema -- always check the Actor's documentation before running.\n\n---\n\n## Core Workflows\n\n### 1. Run an Actor Synchronously and Get Results\n\nExecute an Actor and immediately retrieve its dataset items in a single call. Best for quick scraping jobs.\n\n**Tool:** `APIFY_RUN_ACTOR_SYNC_GET_DATASET_ITEMS`\n\nKey parameters:\n- `actorId` (required) -- Actor ID in format `username/actor-name` (e.g., `compass/crawler-google-places`)\n- `input` -- JSON input object matching the Actor's schema. Each Actor has unique field names -- check [apify.com/store](https://apify.com/store) for the exact schema.\n- `limit` -- max items to return\n- `offset` -- skip items for pagination\n- `format` -- `json` (default), `csv`, `jsonl`, `html`, `xlsx`, `xml`\n- `timeout` -- run timeout in seconds\n- `waitForFinish` -- max wait time (0-300 seconds)\n- `fields` -- comma-separated list of fields to include\n- `omit` -- comma-separated list of fields to exclude\n\nExample prompt: *\"Run the Google Places scraper for 'restaurants in New York' and return the first 50 results\"*\n\n---\n\n### 2. Run an Actor Asynchronously\n\nTrigger an Actor run without waiting for completion. Use for long-running scraping jobs.\n\n**Tool:** `APIFY_RUN_ACTOR`\n\nKey parameters:\n- `actorId` (required) -- Actor slug or ID\n- `body` -- JSON input object for the Actor\n- `memory` -- memory limit in MB (must be power of 2, minimum 128)\n- `timeout` -- run timeout in seconds\n- `maxItems` -- cap on returned items\n- `build` -- specific build tag (e.g., `latest`, `beta`)\n\nFollow up with `APIFY_GET_DATASET_ITEMS` to retrieve results using the run's `datasetId`.\n\nExample prompt: *\"Start the web scraper Actor for example.com asynchronously with 1024MB memory\"*\n\n---\n\n### 3. Retrieve Dataset Items\n\nFetch data from a specific dataset with pagination, field selection, and filtering.\n\n**Tool:** `APIFY_GET_DATASET_ITEMS`\n\nKey parameters:\n- `datasetId` (required) -- dataset identifier\n- `limit` (default/max 1000) -- items per page\n- `offset` (default 0) -- pagination offset\n- `format` -- `json` (recommended), `csv`, `xlsx`\n- `fields` -- include only specific fields\n- `omit` -- exclude specific fields\n- `clean` -- remove Apify-specific metadata\n- `desc` -- reverse order (newest first)\n\nExample prompt: *\"Get the first 500 items from dataset myDatasetId in JSON format\"*\n\n---\n\n### 4. Inspect Actor Details\n\nView Actor metadata, input schema, and configuration before running it.\n\n**Tool:** `APIFY_GET_ACTOR`\n\nKey parameters:\n- `actorId` (required) -- Actor ID in format `username/actor-name` or hex ID\n\nExample prompt: *\"Show me the details and input schema for the apify/web-scraper Actor\"*\n\n---\n\n### 5. Create Reusable Tasks\n\nConfigure reusable Actor tasks with preset inputs for recurring scraping jobs.\n\n**Tool:** `APIFY_CREATE_TASK`\n\nConfigure a task once, then trigger it repeatedly with consistent input parameters. Useful for scheduled or recurring data collection workflows.\n\nExample prompt: *\"Create an Apify task for the Google Search scraper with default query 'AI startups' and US location\"*\n\n---\n\n### 6. Manage Runs and Datasets\n\nList Actor runs, browse datasets, and inspect run details for monitoring and debugging.\n\n**Tools:** `APIFY_GET_LIST_OF_RUNS`, `APIFY_DATASETS_GET`, `APIFY_DATASET_GET`, `APIFY_GET_LOG`\n\nFor listing runs:\n- Filter by Actor and optionally by status\n- Get `datasetId` from run details for data retrieval\n\nFor dataset management:\n- `APIFY_DATASETS_GET` -- list all your datasets with pagination\n- `APIFY_DATASET_GET` -- get metadata for a specific dataset\n\nFor debugging:\n- `APIFY_GET_LOG` -- retrieve execution logs for a run or build\n\nExample prompt: *\"List the last 10 runs for the web scraper Actor and show logs for the most recent one\"*\n\n---\n\n## Known Pitfalls\n\n- **Actor input schemas vary wildly:** Every Actor has its own unique input fields. Generic field names like `queries` or `search_terms` will be rejected. Always check the Actor's page on [apify.com/store](https://apify.com/store) for exact field names (e.g., `searchStringsArray` for Google Maps, `startUrls` for web scrapers).\n- **URL format requirements:** Always include the full protocol (`https://` or `http://`) in URLs. Many Actors require URLs as objects with a `url` property: `{\"startUrls\": [{\"url\": \"https://example.com\"}]}`.\n- **Dataset pagination cap:** `APIFY_GET_DATASET_ITEMS` has a max `limit` of 1000 per call. For large datasets, loop with `offset` to collect all items.\n- **Enum values are lowercase:** Most Actors expect lowercase enum values (e.g., `relevance` not `RELEVANCE`, `all` not `ALL`).\n- **Sync timeout at 5 minutes:** `APIFY_RUN_ACTOR_SYNC_GET_DATASET_ITEMS` has a maximum `waitForFinish` of 300 seconds. For longer runs, use `APIFY_RUN_ACTOR` (async) and poll with `APIFY_GET_DATASET_ITEMS`.\n- **Data volume costs:** Large datasets can be expensive to fetch. Prefer moderate limits and incremental processing to avoid timeouts or memory pressure.\n- **JSON format recommended:** While CSV/XLSX formats are available, JSON is the most reliable for automated processing. Avoid CSV/XLSX for downstream automation.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `APIFY_RUN_ACTOR_SYNC_GET_DATASET_ITEMS` | Run Actor synchronously and get results immediately |\n| `APIFY_RUN_ACTOR` | Run Actor asynchronously (trigger and return) |\n| `APIFY_RUN_ACTOR_SYNC` | Run Actor synchronously, return output record |\n| `APIFY_GET_ACTOR` | Get Actor metadata and input schema |\n| `APIFY_GET_DATASET_ITEMS` | Retrieve items from a dataset (paginated) |\n| `APIFY_DATASET_GET` | Get dataset metadata (item count, etc.) |\n| `APIFY_DATASETS_GET` | List all user datasets |\n| `APIFY_CREATE_TASK` | Create a reusable Actor task |\n| `APIFY_GET_TASK_INPUT` | Inspect a task's stored input |\n| `APIFY_GET_LIST_OF_RUNS` | List runs for an Actor |\n| `APIFY_GET_LOG` | Get execution logs for a run |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apilio-automation/SKILL.md",
    "content": "---\nname: apilio-automation\ndescription: \"Automate Apilio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apilio Automation via Rube MCP\n\nAutomate Apilio operations through Composio's Apilio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apilio](https://composio.dev/toolkits/apilio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apilio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apilio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apilio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apilio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apilio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apilio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apilio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apilio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apipie-ai-automation/SKILL.md",
    "content": "---\nname: apipie-ai-automation\ndescription: \"Automate Apipie AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apipie AI Automation via Rube MCP\n\nAutomate Apipie AI operations through Composio's Apipie AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apipie_ai](https://composio.dev/toolkits/apipie_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apipie AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apipie_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apipie_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apipie AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apipie AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apipie_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apipie AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apipie_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apitemplate-io-automation/SKILL.md",
    "content": "---\nname: apitemplate-io-automation\ndescription: \"Automate Apitemplate IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apitemplate IO Automation via Rube MCP\n\nAutomate Apitemplate IO operations through Composio's Apitemplate IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apitemplate_io](https://composio.dev/toolkits/apitemplate_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apitemplate IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apitemplate_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apitemplate_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apitemplate IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apitemplate IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apitemplate_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apitemplate IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apitemplate_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apiverve-automation/SKILL.md",
    "content": "---\nname: apiverve-automation\ndescription: \"Automate Apiverve tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Apiverve Automation via Rube MCP\n\nAutomate Apiverve operations through Composio's Apiverve toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/apiverve](https://composio.dev/toolkits/apiverve)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Apiverve connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `apiverve`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `apiverve`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Apiverve operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Apiverve task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"apiverve\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Apiverve-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `apiverve` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/apollo-automation/SKILL.md",
    "content": "---\nname: Apollo Automation\ndescription: \"Automate Apollo.io lead generation -- search organizations, discover contacts, enrich prospect data, manage contact stages, and build targeted outreach lists -- using natural language through the Composio MCP integration.\"\ncategory: sales-intelligence\nrequires:\n  mcp:\n    - rube\n---\n\n# Apollo Automation\n\nSupercharge your sales prospecting with Apollo.io -- search companies, discover decision-makers, enrich contact data with emails and phone numbers, and manage your sales pipeline stages -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/apollo](https://composio.dev/toolkits/apollo)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Apollo.io account when prompted (API key authentication).\n3. Start issuing natural language commands to prospect and enrich leads.\n\n---\n\n## Core Workflows\n\n### 1. Search Organizations\nFind target companies using filters like name, location, employee count, and industry keywords.\n\n**Tool:** `APOLLO_ORGANIZATION_SEARCH`\n\n**Example prompt:**\n> \"Find SaaS companies in Texas with 50-500 employees on Apollo\"\n\n**Key parameters:**\n- `q_organization_name` -- Partial name match (e.g., \"Apollo\" matches \"Apollo Inc.\")\n- `organization_locations` -- HQ locations to include (e.g., \"texas\", \"tokyo\")\n- `organization_not_locations` -- HQ locations to exclude\n- `organization_num_employees_ranges` -- Employee ranges in \"min,max\" format (e.g., \"50,500\")\n- `q_organization_keyword_tags` -- Industry keywords (e.g., \"software\", \"healthcare\")\n- `page` / `per_page` -- Pagination (max 100 per page, max 500 pages)\n\n---\n\n### 2. Discover People at Companies\nSearch Apollo's contact database for people matching title, seniority, location, and company criteria.\n\n**Tool:** `APOLLO_PEOPLE_SEARCH`\n\n**Example prompt:**\n> \"Find VPs of Sales at microsoft.com and apollo.io\"\n\n**Key parameters:**\n- `person_titles` -- Job titles (e.g., \"VP of Sales\", \"CTO\")\n- `person_seniorities` -- Seniority levels (e.g., \"director\", \"vp\", \"senior\")\n- `person_locations` -- Geographic locations of people\n- `q_organization_domains` -- Company domains (e.g., \"apollo.io\" -- exclude \"www.\")\n- `organization_ids` -- Apollo company IDs from Organization Search\n- `contact_email_status` -- Filter by email status: \"verified\", \"unverified\", \"likely to engage\"\n- `page` / `per_page` -- Pagination (max 100 per page)\n\n---\n\n### 3. Enrich Individual Contacts\nGet comprehensive data (email, phone, LinkedIn, company info) for a single person using their email, LinkedIn URL, or name + company.\n\n**Tool:** `APOLLO_PEOPLE_ENRICHMENT`\n\n**Example prompt:**\n> \"Enrich Tim Zheng at Apollo.io on Apollo\"\n\n**Key parameters (at least one identifier required):**\n- `email` -- Person's email address\n- `linkedin_url` -- Full LinkedIn profile URL\n- `first_name` + `last_name` + (`organization_name` or `domain`) -- Name-based matching\n- `domain` -- Bare hostname without protocol (e.g., \"apollo.io\", not \"https://apollo.io\")\n- `reveal_personal_emails` -- Set true to get personal emails (may use extra credits)\n- `reveal_phone_number` -- Set true for phone numbers (requires `webhook_url`)\n\n---\n\n### 4. Bulk Enrich Prospects\nEnrich up to 10 people simultaneously for efficient batch processing.\n\n**Tool:** `APOLLO_BULK_PEOPLE_ENRICHMENT`\n\n**Example prompt:**\n> \"Bulk enrich these 5 leads with their Apollo data: [list of names/emails]\"\n\n**Key parameters:**\n- `details` (required) -- Array of 1-10 person objects, each with identifiers like `email`, `linkedin_url`, `first_name`, `last_name`, `domain`, `company_name`\n- `reveal_personal_emails` -- Include personal emails (extra credits)\n- `reveal_phone_number` -- Include phone numbers (requires `webhook_url`)\n\n---\n\n### 5. Manage Contact Pipeline Stages\nList available stages and update contacts through your sales funnel.\n\n**Tools:** `APOLLO_LIST_CONTACT_STAGES`, `APOLLO_UPDATE_CONTACT_STAGE`\n\n**Example prompt:**\n> \"Move contacts X and Y to the 'Qualified' stage in Apollo\"\n\n**Key parameters for listing stages:** None required.\n\n**Key parameters for updating stage:**\n- `contact_ids` (required) -- Array of contact IDs to update\n- `contact_stage_id` (required) -- Target stage ID (from List Contact Stages)\n\n---\n\n### 6. Create and Search Saved Contacts\nCreate new contact records and search your existing Apollo contact database.\n\n**Tools:** `APOLLO_CREATE_CONTACT`, `APOLLO_SEARCH_CONTACTS`\n\n**Example prompt:**\n> \"Search my Apollo contacts for anyone at Stripe\"\n\n**Key parameters for search:**\n- Keyword search, stage ID filtering, sorting options\n- `page` / `per_page` -- Pagination\n\n**Key parameters for create:**\n- `first_name`, `last_name`, `email`, `organization_name`\n- `account_id` -- Link to an organization\n- `contact_stage_id` -- Initial sales stage\n\n---\n\n## Known Pitfalls\n\n- **Organization domains can be empty**: Some organizations from `APOLLO_ORGANIZATION_SEARCH` return missing or empty domain fields. Use `APOLLO_ORGANIZATION_ENRICHMENT` to validate domains before relying on them.\n- **HTTP 403 means config issues**: A 403 response indicates API key or plan access problems -- do not retry. Fix your credentials or plan first.\n- **People search returns obfuscated data**: `APOLLO_PEOPLE_SEARCH` may show `has_email`/`has_direct_phone` flags or obfuscated fields instead of full contact details. Use `APOLLO_PEOPLE_ENRICHMENT` to get complete information.\n- **Pagination limits are strict**: People search supports `per_page` up to 100 and max 500 pages. Stopping early can miss large portions of the result set.\n- **Bulk enrichment has small batch limits**: `APOLLO_BULK_PEOPLE_ENRICHMENT` accepts only 10 items per call. It can return `status='success'` with `missing_records > 0` when identifiers are insufficient -- retry individual records with `APOLLO_PEOPLE_ENRICHMENT`.\n- **No automatic deduplication**: `APOLLO_CREATE_CONTACT` does not deduplicate. Check for existing contacts first with `APOLLO_SEARCH_CONTACTS`.\n- **Domain format matters**: Always use bare hostnames (e.g., \"apollo.io\") without protocol prefixes (\"https://\") or \"www.\" prefix.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| Search organizations | `APOLLO_ORGANIZATION_SEARCH` | None (optional filters) |\n| Enrich organization | `APOLLO_ORGANIZATION_ENRICHMENT` | `domain` |\n| Bulk enrich orgs | `APOLLO_BULK_ORGANIZATION_ENRICHMENT` | `domains` |\n| Search people | `APOLLO_PEOPLE_SEARCH` | None (optional filters) |\n| Enrich person | `APOLLO_PEOPLE_ENRICHMENT` | One of: `email`, `linkedin_url`, or name+company |\n| Bulk enrich people | `APOLLO_BULK_PEOPLE_ENRICHMENT` | `details` (1-10 person objects) |\n| List contact stages | `APOLLO_LIST_CONTACT_STAGES` | None |\n| Update contact stage | `APOLLO_UPDATE_CONTACT_STAGE` | `contact_ids`, `contact_stage_id` |\n| Create contact | `APOLLO_CREATE_CONTACT` | Name + identifiers |\n| Search contacts | `APOLLO_SEARCH_CONTACTS` | None (optional filters) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/appcircle-automation/SKILL.md",
    "content": "---\nname: appcircle-automation\ndescription: \"Automate Appcircle tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Appcircle Automation via Rube MCP\n\nAutomate Appcircle operations through Composio's Appcircle toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/appcircle](https://composio.dev/toolkits/appcircle)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Appcircle connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `appcircle`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `appcircle`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Appcircle operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Appcircle task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"appcircle\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Appcircle-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `appcircle` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/appdrag-automation/SKILL.md",
    "content": "---\nname: appdrag-automation\ndescription: \"Automate Appdrag tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Appdrag Automation via Rube MCP\n\nAutomate Appdrag operations through Composio's Appdrag toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/appdrag](https://composio.dev/toolkits/appdrag)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Appdrag connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `appdrag`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `appdrag`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Appdrag operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Appdrag task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"appdrag\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Appdrag-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `appdrag` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/appointo-automation/SKILL.md",
    "content": "---\nname: appointo-automation\ndescription: \"Automate Appointo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Appointo Automation via Rube MCP\n\nAutomate Appointo operations through Composio's Appointo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/appointo](https://composio.dev/toolkits/appointo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Appointo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `appointo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `appointo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Appointo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Appointo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"appointo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Appointo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `appointo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/appsflyer-automation/SKILL.md",
    "content": "---\nname: appsflyer-automation\ndescription: \"Automate Appsflyer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Appsflyer Automation via Rube MCP\n\nAutomate Appsflyer operations through Composio's Appsflyer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/appsflyer](https://composio.dev/toolkits/appsflyer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Appsflyer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `appsflyer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `appsflyer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Appsflyer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Appsflyer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"appsflyer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Appsflyer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `appsflyer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/appveyor-automation/SKILL.md",
    "content": "---\nname: appveyor-automation\ndescription: \"Automate Appveyor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Appveyor Automation via Rube MCP\n\nAutomate Appveyor operations through Composio's Appveyor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/appveyor](https://composio.dev/toolkits/appveyor)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Appveyor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `appveyor`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `appveyor`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Appveyor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Appveyor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"appveyor\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Appveyor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `appveyor` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/aryn-automation/SKILL.md",
    "content": "---\nname: aryn-automation\ndescription: \"Automate Aryn tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Aryn Automation via Rube MCP\n\nAutomate Aryn operations through Composio's Aryn toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/aryn](https://composio.dev/toolkits/aryn)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Aryn connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `aryn`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `aryn`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Aryn operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Aryn task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"aryn\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Aryn-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `aryn` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ascora-automation/SKILL.md",
    "content": "---\nname: ascora-automation\ndescription: \"Automate Ascora tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ascora Automation via Rube MCP\n\nAutomate Ascora operations through Composio's Ascora toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ascora](https://composio.dev/toolkits/ascora)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ascora connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ascora`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ascora`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ascora operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ascora task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ascora\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ascora-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ascora` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ashby-automation/SKILL.md",
    "content": "---\nname: Ashby Automation\ndescription: \"Automate recruiting and hiring workflows in Ashby -- manage candidates, jobs, applications, interviews, and notes through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Ashby Automation\n\nAutomate your Ashby ATS recruiting operations directly from Claude Code. Create candidates, post jobs, manage applications, view interview schedules, and search your talent pipeline -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/ashby](https://composio.dev/toolkits/ashby)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Ashby account through the connection link provided\n3. Start automating your recruiting workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Manage Candidates\n\nCreate, list, search, update, and retrieve detailed candidate information.\n\n**Tools:** `ASHBY_CREATE_CANDIDATE`, `ASHBY_LIST_CANDIDATES`, `ASHBY_SEARCH_CANDIDATES`, `ASHBY_GET_CANDIDATE_INFO`, `ASHBY_UPDATE_CANDIDATE`\n\n```\nCreate a candidate named \"Jane Smith\" with email jane@example.com and LinkedIn profile https://linkedin.com/in/janesmith\n```\n\nKey parameters for `ASHBY_CREATE_CANDIDATE`:\n- `name` (required) -- full name of the candidate\n- `email` -- primary email address\n- `phoneNumber`, `linkedInUrl`, `githubUrl`, `websiteUrl` -- contact/social profiles\n\nKey parameters for `ASHBY_SEARCH_CANDIDATES`:\n- `email` -- exact email match\n- `name` -- partial name match\n\nKey parameters for `ASHBY_LIST_CANDIDATES`:\n- `perPage` (max 100) / `cursor` -- pagination\n- `syncToken` -- for incremental updates since last sync\n\n### 2. Create and List Jobs\n\nPost new job openings and browse existing positions.\n\n**Tools:** `ASHBY_CREATE_JOB`, `ASHBY_LIST_JOBS`, `ASHBY_GET_JOB_INFO`\n\n```\nCreate a new \"Senior Software Engineer\" job in team dept-123 at location loc-456 with brand brand-789\n```\n\nKey parameters for `ASHBY_CREATE_JOB`:\n- `title` (required) -- job title\n- `teamId` (required) -- department/team ID (from list departments)\n- `locationId` (required) -- office location ID (from list locations)\n- `brandId` (required) -- employer brand ID (from list brands)\n- `defaultInterviewPlanId` -- required to open the job for applications\n- `jobTemplateId` -- pre-populate from a template\n\nKey parameters for `ASHBY_LIST_JOBS`:\n- `perPage` (max 100) / `cursor` / `syncToken` -- pagination and incremental sync\n\n**Note:** Newly created jobs start in \"Draft\" status. You must set a `defaultInterviewPlanId` to open/publish the job.\n\n### 3. Manage Applications\n\nCreate applications to connect candidates to jobs and track their progress.\n\n**Tools:** `ASHBY_CREATE_APPLICATION`, `ASHBY_LIST_APPLICATIONS`\n\n```\nApply candidate cand-abc123 to job job-xyz789 with source src-referral\n```\n\nKey parameters for `ASHBY_CREATE_APPLICATION`:\n- `candidateId` (required) -- UUID of an existing candidate\n- `jobId` (required) -- UUID of an existing job\n- `sourceId` -- UUID of the application source (LinkedIn, Referral, etc.)\n- `creditedToUserId` -- UUID of recruiter/referrer to credit\n- `interviewStageId` -- place directly into a specific stage (defaults to first stage)\n\nKey parameters for `ASHBY_LIST_APPLICATIONS`:\n- `perPage` (max 100) / `cursor` / `syncToken` -- pagination and incremental sync\n\n### 4. View Interview Schedules\n\nList scheduled interviews with timing, interviewer, and candidate details.\n\n**Tool:** `ASHBY_LIST_INTERVIEW_SCHEDULES`\n\n```\nShow me all upcoming interview schedules\n```\n\nKey parameters:\n- `perPage` (max 100) / `cursor` -- pagination\n- `syncToken` -- incremental sync for changed schedules\n\n### 5. Candidate Notes\n\nView internal notes, observations, and recruiter comments on candidates.\n\n**Tool:** `ASHBY_LIST_CANDIDATE_NOTES`\n\n```\nShow me all notes for candidate cand-abc123\n```\n\n- Retrieves all notes added by recruiters and hiring team members\n- Useful for reviewing interview feedback and internal assessments\n\n### 6. Pipeline Reporting\n\nCombine listing tools to build hiring pipeline reports.\n\n**Tools:** `ASHBY_LIST_CANDIDATES`, `ASHBY_LIST_APPLICATIONS`, `ASHBY_LIST_JOBS`\n\n```\nList all applications to see the current state of our hiring pipeline\n```\n\n- Use `syncToken` for incremental data fetches (efficient for recurring reports)\n- Combine candidate, application, and job data for full pipeline visibility\n- Paginate through all results with `cursor` for complete datasets\n\n---\n\n## Known Pitfalls\n\n- **Jobs start in Draft:** Newly created jobs via `ASHBY_CREATE_JOB` start in \"Draft\" status and cannot accept applications until a `defaultInterviewPlanId` is set and the job is opened.\n- **Four required fields for jobs:** `ASHBY_CREATE_JOB` requires `title`, `teamId`, `locationId`, and `brandId`. Use list departments, locations, and brands endpoints to discover valid IDs.\n- **Candidate before application:** A candidate must exist before creating an application. Always create or find the candidate first, then create the application.\n- **Cursor-based pagination:** All list endpoints use cursor-based pagination with `perPage` (max 100) and `cursor`. You cannot jump to arbitrary pages -- you must iterate sequentially.\n- **`syncToken` for efficiency:** Use `syncToken` from previous responses to fetch only changed records. This dramatically reduces API calls for recurring workflows.\n- **UUID format everywhere:** All IDs (candidates, jobs, applications, stages) are UUIDs. Passing malformed IDs returns 400 errors.\n- **Search limitations:** `ASHBY_SEARCH_CANDIDATES` supports exact email match or partial name match, but not combined queries or other fields. For broader searches, use `ASHBY_LIST_CANDIDATES` with pagination.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `ASHBY_CREATE_CANDIDATE` | Create a new candidate (requires `name`) |\n| `ASHBY_LIST_CANDIDATES` | List all candidates with pagination and sync |\n| `ASHBY_SEARCH_CANDIDATES` | Search candidates by email or name |\n| `ASHBY_GET_CANDIDATE_INFO` | Get full candidate details (requires `candidateId`) |\n| `ASHBY_UPDATE_CANDIDATE` | Update candidate profile information |\n| `ASHBY_LIST_CANDIDATE_NOTES` | List internal notes for a candidate |\n| `ASHBY_CREATE_JOB` | Create a job opening (requires `title`, `teamId`, `locationId`, `brandId`) |\n| `ASHBY_LIST_JOBS` | List all jobs with pagination and sync |\n| `ASHBY_GET_JOB_INFO` | Get full job details by ID |\n| `ASHBY_CREATE_APPLICATION` | Apply a candidate to a job (requires `candidateId`, `jobId`) |\n| `ASHBY_LIST_APPLICATIONS` | List all applications with pagination and sync |\n| `ASHBY_LIST_INTERVIEW_SCHEDULES` | List scheduled interviews with pagination |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/asin-data-api-automation/SKILL.md",
    "content": "---\nname: asin-data-api-automation\ndescription: \"Automate Asin Data API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Asin Data API Automation via Rube MCP\n\nAutomate Asin Data API operations through Composio's Asin Data API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/asin_data_api](https://composio.dev/toolkits/asin_data_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Asin Data API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `asin_data_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `asin_data_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Asin Data API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Asin Data API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"asin_data_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Asin Data API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `asin_data_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/astica-ai-automation/SKILL.md",
    "content": "---\nname: astica-ai-automation\ndescription: \"Automate Astica AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Astica AI Automation via Rube MCP\n\nAutomate Astica AI operations through Composio's Astica AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/astica_ai](https://composio.dev/toolkits/astica_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Astica AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `astica_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `astica_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Astica AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Astica AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"astica_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Astica AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `astica_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/async-interview-automation/SKILL.md",
    "content": "---\nname: async-interview-automation\ndescription: \"Automate Async Interview tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Async Interview Automation via Rube MCP\n\nAutomate Async Interview operations through Composio's Async Interview toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/async_interview](https://composio.dev/toolkits/async_interview)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Async Interview connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `async_interview`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `async_interview`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Async Interview operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Async Interview task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"async_interview\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Async Interview-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `async_interview` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/atlassian-automation/SKILL.md",
    "content": "---\nname: atlassian-automation\ndescription: \"Automate Atlassian tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Atlassian Automation via Rube MCP\n\nAutomate Atlassian operations through Composio's Atlassian toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/atlassian](https://composio.dev/toolkits/atlassian)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Atlassian connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `atlassian`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `atlassian`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Atlassian operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Atlassian task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"atlassian\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Atlassian-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `atlassian` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/attio-automation/SKILL.md",
    "content": "---\nname: Attio Automation\ndescription: \"Automate Attio CRM operations -- search records, query contacts and companies with advanced filters, manage notes, list attributes, and navigate your relationship data -- using natural language through the Composio MCP integration.\"\ncategory: crm\nrequires:\n  mcp:\n    - rube\n---\n\n# Attio Automation\n\nManage your Attio CRM workspace -- fuzzy search across people and companies, run complex filtered queries, browse notes, discover object schemas, and list records -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/attio](https://composio.dev/toolkits/attio)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Attio account when prompted (OAuth authentication).\n3. Start issuing natural language commands to manage your CRM data.\n\n---\n\n## Core Workflows\n\n### 1. Fuzzy Search Across Records\nSearch for people, companies, deals, or any object by name, domain, email, phone, or social handle.\n\n**Tool:** `ATTIO_SEARCH_RECORDS`\n\n**Example prompt:**\n> \"Search Attio for anyone named Alan Mathis\"\n\n**Key parameters (all required):**\n- `query` -- Search string (max 256 characters). Empty string returns default results.\n- `objects` -- Array of object slugs to search (e.g., `[\"people\"]`, `[\"people\", \"companies\"]`, `[\"deals\"]`)\n- `request_as` -- Context: use `{\"type\": \"workspace\"}` for full workspace search, or specify a workspace member\n\n---\n\n### 2. Advanced Filtered Queries\nQuery records with server-side filtering, sorting, and complex conditions -- far more powerful than fuzzy search.\n\n**Tool:** `ATTIO_QUERY_RECORDS`\n\n**Example prompt:**\n> \"Find all companies in Attio created after January 2025 sorted by name\"\n\n**Key parameters:**\n- `object` (required) -- Object slug or UUID (e.g., \"people\", \"companies\", \"deals\")\n- `filter` -- Attio filter object with operators like `$eq`, `$contains`, `$gte`, `$and`, `$or`\n- `sorts` -- Array of sort specifications with `direction` (\"asc\"/\"desc\") and `attribute`\n- `limit` -- Max records to return (up to 500)\n- `offset` -- Pagination offset\n\n**Filter examples:**\n```json\n{\"name\": {\"first_name\": {\"$contains\": \"John\"}}}\n{\"email_addresses\": {\"$contains\": \"@example.com\"}}\n{\"created_at\": {\"$gte\": \"2025-01-01T00:00:00.000Z\"}}\n```\n\n---\n\n### 3. Find Records by ID or Attributes\nLook up a specific record by its unique ID or search by unique attribute values.\n\n**Tool:** `ATTIO_FIND_RECORD`\n\n**Example prompt:**\n> \"Find the Attio company with domain example.com\"\n\n**Key parameters:**\n- `object_id` (required) -- Object type slug: \"people\", \"companies\", \"deals\", \"users\", \"workspaces\"\n- `record_id` -- Direct lookup by UUID (optional)\n- `attributes` -- Dictionary of attribute filters (e.g., `{\"email_addresses\": \"john@example.com\"}`)\n- `limit` -- Max records (up to 1000)\n- `offset` -- Pagination offset\n\n---\n\n### 4. Browse and Filter Notes\nList notes across the workspace or filter by specific parent objects and records.\n\n**Tool:** `ATTIO_LIST_NOTES`\n\n**Example prompt:**\n> \"Show the last 10 notes on the Acme Corp company record in Attio\"\n\n**Key parameters:**\n- `parent_object` -- Object slug (e.g., \"people\", \"companies\", \"deals\") -- requires `parent_record_id`\n- `parent_record_id` -- UUID of the parent record -- requires `parent_object`\n- `limit` -- Max notes to return (1-50, default 10)\n- `offset` -- Number of results to skip\n\n---\n\n### 5. Discover Object Schemas and Attributes\nUnderstand your workspace structure by listing objects and their attribute definitions.\n\n**Tools:** `ATTIO_GET_OBJECT`, `ATTIO_LIST_ATTRIBUTES`\n\n**Example prompt:**\n> \"What attributes does the companies object have in Attio?\"\n\n**Key parameters for Get Object:**\n- `object_id` -- Object slug or UUID\n\n**Key parameters for List Attributes:**\n- `target` -- \"objects\" or \"lists\"\n- `identifier` -- Object or list ID/slug\n\n---\n\n### 6. List All Records\nRetrieve records from a specific object type with simple pagination, returned in creation order.\n\n**Tool:** `ATTIO_LIST_RECORDS`\n\n**Example prompt:**\n> \"List the first 100 people records in Attio\"\n\n**Key parameters:**\n- Object type identifier\n- Pagination parameters\n\n---\n\n## Known Pitfalls\n\n- **Timestamp format is critical**: ALL timestamp comparisons (`created_at`, `updated_at`, custom timestamps) MUST use ISO8601 string format (e.g., `2025-01-01T00:00:00.000Z`). Unix timestamps or numeric values cause \"Invalid timestamp value\" errors.\n- **Name attributes must be nested**: The `name` attribute has sub-properties (`first_name`, `last_name`, `full_name`) that MUST be nested under `name`. Correct: `{\"name\": {\"first_name\": {\"$contains\": \"John\"}}}`. Wrong: `{\"first_name\": {...}}` -- this fails with \"unknown_filter_attribute_slug\".\n- **Email operators are limited**: `email_addresses` supports `$eq`, `$contains`, `$starts_with`, `$ends_with` but NOT `$not_empty`.\n- **Record-reference attributes need path filtering**: For attributes that reference other records (e.g., \"team\", \"company\"), use path-based filtering, not nested syntax. Example: `{\"path\": [[\"companies\", \"team\"], [\"people\", \"name\"]], \"constraints\": {\"first_name\": {\"$eq\": \"John\"}}}`.\n- **\"lists\" is not an object type**: Do not use \"lists\" as an `object_id`. Use list-specific actions for list operations.\n- **Search is eventually consistent**: `ATTIO_SEARCH_RECORDS` returns eventually consistent results. For guaranteed up-to-date results, use `ATTIO_QUERY_RECORDS` instead.\n- **Attribute slugs vary by workspace**: System attributes (e.g., \"email_addresses\", \"name\") are consistent, but custom attributes vary. Use `ATTIO_LIST_ATTRIBUTES` to discover valid slugs for your workspace.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| Fuzzy search records | `ATTIO_SEARCH_RECORDS` | `query`, `objects`, `request_as` |\n| Query with filters | `ATTIO_QUERY_RECORDS` | `object` |\n| Find record by ID/attributes | `ATTIO_FIND_RECORD` | `object_id` |\n| List notes | `ATTIO_LIST_NOTES` | None (optional filters) |\n| Get object schema | `ATTIO_GET_OBJECT` | `object_id` |\n| List attributes | `ATTIO_LIST_ATTRIBUTES` | `target`, `identifier` |\n| List records | `ATTIO_LIST_RECORDS` | Object type |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/auth0-automation/SKILL.md",
    "content": "---\nname: auth0-automation\ndescription: \"Automate Auth0 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Auth0 Automation via Rube MCP\n\nAutomate Auth0 operations through Composio's Auth0 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/auth0](https://composio.dev/toolkits/auth0)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Auth0 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `auth0`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `auth0`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Auth0 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Auth0 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"auth0\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Auth0-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `auth0` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/autobound-automation/SKILL.md",
    "content": "---\nname: autobound-automation\ndescription: \"Automate Autobound tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Autobound Automation via Rube MCP\n\nAutomate Autobound operations through Composio's Autobound toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/autobound](https://composio.dev/toolkits/autobound)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Autobound connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `autobound`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `autobound`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Autobound operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Autobound task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"autobound\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Autobound-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `autobound` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/autom-automation/SKILL.md",
    "content": "---\nname: autom-automation\ndescription: \"Automate Autom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Autom Automation via Rube MCP\n\nAutomate Autom operations through Composio's Autom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/autom](https://composio.dev/toolkits/autom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Autom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `autom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `autom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Autom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Autom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"autom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Autom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `autom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/axonaut-automation/SKILL.md",
    "content": "---\nname: axonaut-automation\ndescription: \"Automate Axonaut tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Axonaut Automation via Rube MCP\n\nAutomate Axonaut operations through Composio's Axonaut toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/axonaut](https://composio.dev/toolkits/axonaut)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Axonaut connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `axonaut`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `axonaut`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Axonaut operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Axonaut task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"axonaut\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Axonaut-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `axonaut` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ayrshare-automation/SKILL.md",
    "content": "---\nname: ayrshare-automation\ndescription: \"Automate Ayrshare tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ayrshare Automation via Rube MCP\n\nAutomate Ayrshare operations through Composio's Ayrshare toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ayrshare](https://composio.dev/toolkits/ayrshare)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ayrshare connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ayrshare`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ayrshare`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ayrshare operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ayrshare task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ayrshare\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ayrshare-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ayrshare` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/backendless-automation/SKILL.md",
    "content": "---\nname: backendless-automation\ndescription: \"Automate Backendless tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Backendless Automation via Rube MCP\n\nAutomate Backendless operations through Composio's Backendless toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/backendless](https://composio.dev/toolkits/backendless)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Backendless connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `backendless`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `backendless`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Backendless operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Backendless task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"backendless\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Backendless-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `backendless` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bannerbear-automation/SKILL.md",
    "content": "---\nname: bannerbear-automation\ndescription: \"Automate Bannerbear tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bannerbear Automation via Rube MCP\n\nAutomate Bannerbear operations through Composio's Bannerbear toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bannerbear](https://composio.dev/toolkits/bannerbear)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bannerbear connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bannerbear`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bannerbear`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bannerbear operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bannerbear task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bannerbear\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bannerbear-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bannerbear` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bart-automation/SKILL.md",
    "content": "---\nname: bart-automation\ndescription: \"Automate Bart tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bart Automation via Rube MCP\n\nAutomate Bart operations through Composio's Bart toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bart](https://composio.dev/toolkits/bart)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bart connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bart`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bart`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bart operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bart task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bart\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bart-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bart` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/baselinker-automation/SKILL.md",
    "content": "---\nname: baselinker-automation\ndescription: \"Automate Baselinker tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Baselinker Automation via Rube MCP\n\nAutomate Baselinker operations through Composio's Baselinker toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/baselinker](https://composio.dev/toolkits/baselinker)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Baselinker connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `baselinker`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `baselinker`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Baselinker operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Baselinker task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"baselinker\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Baselinker-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `baselinker` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/baserow-automation/SKILL.md",
    "content": "---\nname: baserow-automation\ndescription: \"Automate Baserow tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Baserow Automation via Rube MCP\n\nAutomate Baserow operations through Composio's Baserow toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/baserow](https://composio.dev/toolkits/baserow)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Baserow connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `baserow`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `baserow`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Baserow operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Baserow task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"baserow\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Baserow-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `baserow` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/basin-automation/SKILL.md",
    "content": "---\nname: basin-automation\ndescription: \"Automate Basin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Basin Automation via Rube MCP\n\nAutomate Basin operations through Composio's Basin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/basin](https://composio.dev/toolkits/basin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Basin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `basin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `basin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Basin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Basin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"basin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Basin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `basin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/battlenet-automation/SKILL.md",
    "content": "---\nname: battlenet-automation\ndescription: \"Automate Battlenet tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Battlenet Automation via Rube MCP\n\nAutomate Battlenet operations through Composio's Battlenet toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/battlenet](https://composio.dev/toolkits/battlenet)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Battlenet connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `battlenet`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `battlenet`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Battlenet operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Battlenet task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"battlenet\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Battlenet-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `battlenet` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/beaconchain-automation/SKILL.md",
    "content": "---\nname: beaconchain-automation\ndescription: \"Automate Beaconchain tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Beaconchain Automation via Rube MCP\n\nAutomate Beaconchain operations through Composio's Beaconchain toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/beaconchain](https://composio.dev/toolkits/beaconchain)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Beaconchain connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconchain`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconchain`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Beaconchain operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Beaconchain task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"beaconchain\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Beaconchain-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconchain` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/beaconstac-automation/SKILL.md",
    "content": "---\nname: beaconstac-automation\ndescription: \"Automate Beaconstac tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Beaconstac Automation via Rube MCP\n\nAutomate Beaconstac operations through Composio's Beaconstac toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/beaconstac](https://composio.dev/toolkits/beaconstac)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Beaconstac connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconstac`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconstac`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Beaconstac operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Beaconstac task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"beaconstac\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Beaconstac-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `beaconstac` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/beamer-automation/SKILL.md",
    "content": "---\nname: beamer-automation\ndescription: \"Automate Beamer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Beamer Automation via Rube MCP\n\nAutomate Beamer operations through Composio's Beamer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/beamer](https://composio.dev/toolkits/beamer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Beamer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `beamer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `beamer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Beamer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Beamer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"beamer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Beamer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `beamer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/beeminder-automation/SKILL.md",
    "content": "---\nname: beeminder-automation\ndescription: \"Automate Beeminder tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Beeminder Automation via Rube MCP\n\nAutomate Beeminder operations through Composio's Beeminder toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/beeminder](https://composio.dev/toolkits/beeminder)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Beeminder connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `beeminder`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `beeminder`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Beeminder operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Beeminder task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"beeminder\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Beeminder-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `beeminder` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bench-automation/SKILL.md",
    "content": "---\nname: bench-automation\ndescription: \"Automate Bench tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bench Automation via Rube MCP\n\nAutomate Bench operations through Composio's Bench toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bench](https://composio.dev/toolkits/bench)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bench connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bench`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bench`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bench operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bench task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bench\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bench-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bench` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/benchmark-email-automation/SKILL.md",
    "content": "---\nname: benchmark-email-automation\ndescription: \"Automate Benchmark Email tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Benchmark Email Automation via Rube MCP\n\nAutomate Benchmark Email operations through Composio's Benchmark Email toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/benchmark_email](https://composio.dev/toolkits/benchmark_email)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Benchmark Email connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `benchmark_email`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `benchmark_email`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Benchmark Email operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Benchmark Email task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"benchmark_email\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Benchmark Email-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `benchmark_email` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/benzinga-automation/SKILL.md",
    "content": "---\nname: benzinga-automation\ndescription: \"Automate Benzinga tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Benzinga Automation via Rube MCP\n\nAutomate Benzinga operations through Composio's Benzinga toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/benzinga](https://composio.dev/toolkits/benzinga)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Benzinga connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `benzinga`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `benzinga`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Benzinga operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Benzinga task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"benzinga\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Benzinga-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `benzinga` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bestbuy-automation/SKILL.md",
    "content": "---\nname: bestbuy-automation\ndescription: \"Automate Bestbuy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bestbuy Automation via Rube MCP\n\nAutomate Bestbuy operations through Composio's Bestbuy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bestbuy](https://composio.dev/toolkits/bestbuy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bestbuy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bestbuy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bestbuy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bestbuy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bestbuy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bestbuy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bestbuy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bestbuy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/better-proposals-automation/SKILL.md",
    "content": "---\nname: better-proposals-automation\ndescription: \"Automate Better Proposals tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Better Proposals Automation via Rube MCP\n\nAutomate Better Proposals operations through Composio's Better Proposals toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/better_proposals](https://composio.dev/toolkits/better_proposals)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Better Proposals connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `better_proposals`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `better_proposals`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Better Proposals operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Better Proposals task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"better_proposals\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Better Proposals-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `better_proposals` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/better-stack-automation/SKILL.md",
    "content": "---\nname: better-stack-automation\ndescription: \"Automate Better Stack tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Better Stack Automation via Rube MCP\n\nAutomate Better Stack operations through Composio's Better Stack toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/better_stack](https://composio.dev/toolkits/better_stack)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Better Stack connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `better_stack`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `better_stack`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Better Stack operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Better Stack task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"better_stack\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Better Stack-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `better_stack` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bidsketch-automation/SKILL.md",
    "content": "---\nname: bidsketch-automation\ndescription: \"Automate Bidsketch tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bidsketch Automation via Rube MCP\n\nAutomate Bidsketch operations through Composio's Bidsketch toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bidsketch](https://composio.dev/toolkits/bidsketch)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bidsketch connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bidsketch`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bidsketch`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bidsketch operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bidsketch task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bidsketch\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bidsketch-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bidsketch` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/big-data-cloud-automation/SKILL.md",
    "content": "---\nname: big-data-cloud-automation\ndescription: \"Automate Big Data Cloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Big Data Cloud Automation via Rube MCP\n\nAutomate Big Data Cloud operations through Composio's Big Data Cloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/big_data_cloud](https://composio.dev/toolkits/big_data_cloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Big Data Cloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `big_data_cloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `big_data_cloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Big Data Cloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Big Data Cloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"big_data_cloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Big Data Cloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `big_data_cloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bigmailer-automation/SKILL.md",
    "content": "---\nname: bigmailer-automation\ndescription: \"Automate Bigmailer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bigmailer Automation via Rube MCP\n\nAutomate Bigmailer operations through Composio's Bigmailer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bigmailer](https://composio.dev/toolkits/bigmailer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bigmailer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bigmailer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bigmailer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bigmailer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bigmailer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bigmailer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bigmailer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bigmailer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bigml-automation/SKILL.md",
    "content": "---\nname: bigml-automation\ndescription: \"Automate Bigml tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bigml Automation via Rube MCP\n\nAutomate Bigml operations through Composio's Bigml toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bigml](https://composio.dev/toolkits/bigml)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bigml connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bigml`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bigml`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bigml operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bigml task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bigml\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bigml-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bigml` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bigpicture-io-automation/SKILL.md",
    "content": "---\nname: bigpicture-io-automation\ndescription: \"Automate Bigpicture IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bigpicture IO Automation via Rube MCP\n\nAutomate Bigpicture IO operations through Composio's Bigpicture IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bigpicture_io](https://composio.dev/toolkits/bigpicture_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bigpicture IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bigpicture_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bigpicture_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bigpicture IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bigpicture IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bigpicture_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bigpicture IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bigpicture_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bitquery-automation/SKILL.md",
    "content": "---\nname: bitquery-automation\ndescription: \"Automate Bitquery tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bitquery Automation via Rube MCP\n\nAutomate Bitquery operations through Composio's Bitquery toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bitquery](https://composio.dev/toolkits/bitquery)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bitquery connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bitquery`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bitquery`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bitquery operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bitquery task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bitquery\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bitquery-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bitquery` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bitwarden-automation/SKILL.md",
    "content": "---\nname: bitwarden-automation\ndescription: \"Automate Bitwarden tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bitwarden Automation via Rube MCP\n\nAutomate Bitwarden operations through Composio's Bitwarden toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bitwarden](https://composio.dev/toolkits/bitwarden)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bitwarden connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bitwarden`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bitwarden`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bitwarden operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bitwarden task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bitwarden\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bitwarden-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bitwarden` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/blackbaud-automation/SKILL.md",
    "content": "---\nname: blackbaud-automation\ndescription: \"Automate Blackbaud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Blackbaud Automation via Rube MCP\n\nAutomate Blackbaud operations through Composio's Blackbaud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/blackbaud](https://composio.dev/toolkits/blackbaud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Blackbaud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `blackbaud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `blackbaud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Blackbaud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Blackbaud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"blackbaud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Blackbaud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `blackbaud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/blackboard-automation/SKILL.md",
    "content": "---\nname: blackboard-automation\ndescription: \"Automate Blackboard tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Blackboard Automation via Rube MCP\n\nAutomate Blackboard operations through Composio's Blackboard toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/blackboard](https://composio.dev/toolkits/blackboard)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Blackboard connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `blackboard`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `blackboard`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Blackboard operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Blackboard task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"blackboard\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Blackboard-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `blackboard` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/blocknative-automation/SKILL.md",
    "content": "---\nname: blocknative-automation\ndescription: \"Automate Blocknative tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Blocknative Automation via Rube MCP\n\nAutomate Blocknative operations through Composio's Blocknative toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/blocknative](https://composio.dev/toolkits/blocknative)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Blocknative connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `blocknative`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `blocknative`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Blocknative operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Blocknative task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"blocknative\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Blocknative-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `blocknative` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/boldsign-automation/SKILL.md",
    "content": "---\nname: boldsign-automation\ndescription: \"Automate Boldsign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Boldsign Automation via Rube MCP\n\nAutomate Boldsign operations through Composio's Boldsign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/boldsign](https://composio.dev/toolkits/boldsign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Boldsign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `boldsign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `boldsign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Boldsign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Boldsign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"boldsign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Boldsign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `boldsign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bolna-automation/SKILL.md",
    "content": "---\nname: bolna-automation\ndescription: \"Automate Bolna tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bolna Automation via Rube MCP\n\nAutomate Bolna operations through Composio's Bolna toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bolna](https://composio.dev/toolkits/bolna)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bolna connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bolna`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bolna`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bolna operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bolna task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bolna\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bolna-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bolna` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/boloforms-automation/SKILL.md",
    "content": "---\nname: boloforms-automation\ndescription: \"Automate Boloforms tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Boloforms Automation via Rube MCP\n\nAutomate Boloforms operations through Composio's Boloforms toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/boloforms](https://composio.dev/toolkits/boloforms)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Boloforms connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `boloforms`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `boloforms`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Boloforms operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Boloforms task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"boloforms\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Boloforms-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `boloforms` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bolt-iot-automation/SKILL.md",
    "content": "---\nname: bolt-iot-automation\ndescription: \"Automate Bolt Iot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bolt Iot Automation via Rube MCP\n\nAutomate Bolt Iot operations through Composio's Bolt Iot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bolt_iot](https://composio.dev/toolkits/bolt_iot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bolt Iot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bolt_iot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bolt_iot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bolt Iot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bolt Iot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bolt_iot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bolt Iot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bolt_iot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bonsai-automation/SKILL.md",
    "content": "---\nname: bonsai-automation\ndescription: \"Automate Bonsai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bonsai Automation via Rube MCP\n\nAutomate Bonsai operations through Composio's Bonsai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bonsai](https://composio.dev/toolkits/bonsai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bonsai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bonsai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bonsai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bonsai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bonsai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bonsai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bonsai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bonsai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bookingmood-automation/SKILL.md",
    "content": "---\nname: bookingmood-automation\ndescription: \"Automate Bookingmood tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bookingmood Automation via Rube MCP\n\nAutomate Bookingmood operations through Composio's Bookingmood toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bookingmood](https://composio.dev/toolkits/bookingmood)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bookingmood connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bookingmood`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bookingmood`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bookingmood operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bookingmood task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bookingmood\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bookingmood-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bookingmood` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/booqable-automation/SKILL.md",
    "content": "---\nname: booqable-automation\ndescription: \"Automate Booqable tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Booqable Automation via Rube MCP\n\nAutomate Booqable operations through Composio's Booqable toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/booqable](https://composio.dev/toolkits/booqable)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Booqable connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `booqable`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `booqable`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Booqable operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Booqable task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"booqable\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Booqable-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `booqable` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/borneo-automation/SKILL.md",
    "content": "---\nname: borneo-automation\ndescription: \"Automate Borneo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Borneo Automation via Rube MCP\n\nAutomate Borneo operations through Composio's Borneo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/borneo](https://composio.dev/toolkits/borneo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Borneo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `borneo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `borneo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Borneo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Borneo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"borneo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Borneo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `borneo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/botbaba-automation/SKILL.md",
    "content": "---\nname: botbaba-automation\ndescription: \"Automate Botbaba tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Botbaba Automation via Rube MCP\n\nAutomate Botbaba operations through Composio's Botbaba toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/botbaba](https://composio.dev/toolkits/botbaba)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Botbaba connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `botbaba`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `botbaba`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Botbaba operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Botbaba task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"botbaba\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Botbaba-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `botbaba` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/botpress-automation/SKILL.md",
    "content": "---\nname: botpress-automation\ndescription: \"Automate Botpress tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Botpress Automation via Rube MCP\n\nAutomate Botpress operations through Composio's Botpress toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/botpress](https://composio.dev/toolkits/botpress)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Botpress connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `botpress`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `botpress`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Botpress operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Botpress task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"botpress\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Botpress-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `botpress` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/botsonic-automation/SKILL.md",
    "content": "---\nname: botsonic-automation\ndescription: \"Automate Botsonic tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Botsonic Automation via Rube MCP\n\nAutomate Botsonic operations through Composio's Botsonic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/botsonic](https://composio.dev/toolkits/botsonic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Botsonic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `botsonic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `botsonic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Botsonic operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Botsonic task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"botsonic\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Botsonic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `botsonic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/botstar-automation/SKILL.md",
    "content": "---\nname: botstar-automation\ndescription: \"Automate Botstar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Botstar Automation via Rube MCP\n\nAutomate Botstar operations through Composio's Botstar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/botstar](https://composio.dev/toolkits/botstar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Botstar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `botstar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `botstar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Botstar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Botstar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"botstar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Botstar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `botstar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bouncer-automation/SKILL.md",
    "content": "---\nname: bouncer-automation\ndescription: \"Automate Bouncer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bouncer Automation via Rube MCP\n\nAutomate Bouncer operations through Composio's Bouncer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bouncer](https://composio.dev/toolkits/bouncer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bouncer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bouncer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bouncer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bouncer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bouncer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bouncer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bouncer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bouncer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/boxhero-automation/SKILL.md",
    "content": "---\nname: boxhero-automation\ndescription: \"Automate Boxhero tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Boxhero Automation via Rube MCP\n\nAutomate Boxhero operations through Composio's Boxhero toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/boxhero](https://composio.dev/toolkits/boxhero)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Boxhero connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `boxhero`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `boxhero`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Boxhero operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Boxhero task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"boxhero\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Boxhero-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `boxhero` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/braintree-automation/SKILL.md",
    "content": "---\nname: Braintree Automation\ndescription: \"Braintree Automation: manage payment processing via Stripe-compatible tools for customers, subscriptions, payment methods, and transactions\"\nrequires:\n  mcp: [rube]\n---\n\n# Braintree Automation\n\nAutomate payment processing operations via Stripe-compatible tooling including managing customers, subscriptions, payment methods, balance transactions, and customer searches. The Composio platform routes Braintree payment workflows through the Stripe toolkit for unified payment management.\n\n**Toolkit docs:** [composio.dev/toolkits/braintree](https://composio.dev/toolkits/braintree)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `stripe` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. Create and Manage Customers\n\nCreate new customers and retrieve existing customer details.\n\n**Tools:**\n- `STRIPE_CREATE_CUSTOMER` -- Create a new customer\n- `STRIPE_GET_CUSTOMERS_CUSTOMER` -- Retrieve a customer by ID\n- `STRIPE_POST_CUSTOMERS_CUSTOMER` -- Update an existing customer\n- `STRIPE_LIST_CUSTOMERS` -- List customers with pagination\n- `STRIPE_GET_V1_CUSTOMERS_SEARCH_CUSTOMERS` -- Search customers by email, name, metadata\n\n**Key Parameters for `STRIPE_CREATE_CUSTOMER`:**\n- `email` -- Customer's primary email address\n- `name` -- Full name or business name\n- `phone` -- Phone number with country code\n- `description` -- Internal reference notes\n- `address` -- Billing address object with `line1`, `city`, `state`, `postal_code`, `country`\n\n**Key Parameters for `STRIPE_GET_V1_CUSTOMERS_SEARCH_CUSTOMERS`:**\n- `query` (required) -- Stripe Search Query Language. Must use `field:value` syntax:\n  - `email:'user@example.com'` -- Exact match (case insensitive)\n  - `name~'John'` -- Substring match (min 3 chars)\n  - `metadata['key']:'value'` -- Metadata search\n  - `created>1609459200` -- Timestamp comparison\n  - Combine with `AND` or `OR` (max 10 clauses, cannot mix)\n- `limit` -- Results per page (1--100, default 10)\n\n**Example:**\n```\nTool: STRIPE_CREATE_CUSTOMER\nArguments:\n  email: \"jane@example.com\"\n  name: \"Jane Doe\"\n  description: \"Enterprise plan customer\"\n  address: {\n    \"line1\": \"123 Main St\",\n    \"city\": \"San Francisco\",\n    \"state\": \"CA\",\n    \"postal_code\": \"94105\",\n    \"country\": \"US\"\n  }\n```\n\n---\n\n### 2. Manage Subscriptions\n\nCreate subscriptions and view customer subscription details.\n\n**Tools:**\n- `STRIPE_CREATE_SUBSCRIPTION` -- Create a new subscription for an existing customer\n- `STRIPE_GET_CUSTOMERS_CUSTOMER_SUBSCRIPTIONS` -- List all subscriptions for a customer\n- `STRIPE_GET_CUSTOMERS_CUSTOMER_SUBS_SUB_EXPOSED_ID` -- Get a specific subscription\n\n**Key Parameters for `STRIPE_CREATE_SUBSCRIPTION`:**\n- `customer` (required) -- Customer ID, e.g., `\"cus_xxxxxxxxxxxxxx\"`\n- `items` (required) -- Array of subscription items, each with:\n  - `price` -- Price ID, e.g., `\"price_xxxxxxxxxxxxxx\"` (use this OR `price_data`)\n  - `price_data` -- Inline price definition with `currency`, `product`, `unit_amount`, `recurring`\n  - `quantity` -- Item quantity\n- `default_payment_method` -- Payment method ID (not required for trials or invoice billing)\n- `trial_period_days` -- Trial days (no payment required during trial)\n- `collection_method` -- `\"charge_automatically\"` (default) or `\"send_invoice\"`\n- `cancel_at_period_end` -- Cancel at end of billing period (boolean)\n\n**Key Parameters for `STRIPE_GET_CUSTOMERS_CUSTOMER_SUBSCRIPTIONS`:**\n- `customer` (required) -- Customer ID\n- `status` -- Filter: `\"active\"`, `\"all\"`, `\"canceled\"`, `\"trialing\"`, `\"past_due\"`, etc.\n- `limit` -- Results per page (1--100, default 10)\n\n**Example:**\n```\nTool: STRIPE_CREATE_SUBSCRIPTION\nArguments:\n  customer: \"cus_abc123\"\n  items: [{\"price\": \"price_xyz789\", \"quantity\": 1}]\n  trial_period_days: 14\n```\n\n---\n\n### 3. Manage Payment Methods\n\nList and attach payment methods to customers.\n\n**Tools:**\n- `STRIPE_GET_CUSTOMERS_CUSTOMER_PAYMENT_METHODS` -- List a customer's payment methods\n- `STRIPE_ATTACH_PAYMENT_METHOD` -- Attach a payment method to a customer\n\n**Key Parameters for `STRIPE_GET_CUSTOMERS_CUSTOMER_PAYMENT_METHODS`:**\n- `customer` (required) -- Customer ID\n- `type` -- Filter by type: `\"card\"`, `\"sepa_debit\"`, `\"us_bank_account\"`, etc.\n- `limit` -- Results per page (1--100, default 10)\n\n**Example:**\n```\nTool: STRIPE_GET_CUSTOMERS_CUSTOMER_PAYMENT_METHODS\nArguments:\n  customer: \"cus_abc123\"\n  type: \"card\"\n  limit: 10\n```\n\n---\n\n### 4. View Balance Transactions\n\nRetrieve the history of balance changes for a customer.\n\n**Tool:** `STRIPE_GET_CUSTOMERS_CUSTOMER_BALANCE_TRANSACTIONS`\n\n**Key Parameters:**\n- `customer` (required) -- Customer ID\n- `created` -- Filter by creation date with comparison operators: `{\"gte\": 1609459200}` or `{\"gt\": 1609459200, \"lt\": 1640995200}`\n- `invoice` -- Filter by related invoice ID\n- `limit` -- Results per page (1--100)\n- `starting_after` / `ending_before` -- Pagination cursors\n\n**Example:**\n```\nTool: STRIPE_GET_CUSTOMERS_CUSTOMER_BALANCE_TRANSACTIONS\nArguments:\n  customer: \"cus_abc123\"\n  limit: 25\n  created: {\"gte\": 1704067200}\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Search query syntax** | `STRIPE_GET_V1_CUSTOMERS_SEARCH_CUSTOMERS` requires field-prefixed queries (e.g., `email:'x'`). Bare strings without field prefixes are invalid and will error. |\n| **Subscription payment method** | `default_payment_method` is not required if using `trial_period_days` or `collection_method='send_invoice'`. Otherwise, the subscription may fail to activate. |\n| **Payment method attachment** | A `PaymentMethod` must be in a detached state before attaching to a customer. Already-attached methods will error. |\n| **Pagination cursors** | Use `starting_after`/`ending_before` with object IDs, not page numbers. Extract the last/first object ID from each response. |\n| **Balance amounts in cents** | All monetary amounts are in the smallest currency unit (e.g., cents for USD). 1000 = $10.00. |\n| **Subscription status default** | `GET_CUSTOMERS_CUSTOMER_SUBSCRIPTIONS` excludes canceled subscriptions by default. Pass `status: \"all\"` to include them. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `STRIPE_CREATE_CUSTOMER` | Create a new customer |\n| `STRIPE_GET_CUSTOMERS_CUSTOMER` | Retrieve a customer by ID |\n| `STRIPE_POST_CUSTOMERS_CUSTOMER` | Update an existing customer |\n| `STRIPE_LIST_CUSTOMERS` | List customers with pagination |\n| `STRIPE_GET_V1_CUSTOMERS_SEARCH_CUSTOMERS` | Search customers by attributes |\n| `STRIPE_CREATE_SUBSCRIPTION` | Create a subscription for a customer |\n| `STRIPE_GET_CUSTOMERS_CUSTOMER_SUBSCRIPTIONS` | List customer subscriptions |\n| `STRIPE_GET_CUSTOMERS_CUSTOMER_SUBS_SUB_EXPOSED_ID` | Get a specific subscription |\n| `STRIPE_GET_CUSTOMERS_CUSTOMER_PAYMENT_METHODS` | List customer payment methods |\n| `STRIPE_ATTACH_PAYMENT_METHOD` | Attach payment method to customer |\n| `STRIPE_GET_CUSTOMERS_CUSTOMER_BALANCE_TRANSACTIONS` | List customer balance transactions |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brandfetch-automation/SKILL.md",
    "content": "---\nname: brandfetch-automation\ndescription: \"Automate Brandfetch tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brandfetch Automation via Rube MCP\n\nAutomate Brandfetch operations through Composio's Brandfetch toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brandfetch](https://composio.dev/toolkits/brandfetch)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brandfetch connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brandfetch`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brandfetch`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brandfetch operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brandfetch task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brandfetch\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brandfetch-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brandfetch` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/breeze-automation/SKILL.md",
    "content": "---\nname: breeze-automation\ndescription: \"Automate Breeze tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Breeze Automation via Rube MCP\n\nAutomate Breeze operations through Composio's Breeze toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/breeze](https://composio.dev/toolkits/breeze)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Breeze connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `breeze`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `breeze`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Breeze operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Breeze task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"breeze\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Breeze-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `breeze` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/breezy-hr-automation/SKILL.md",
    "content": "---\nname: breezy-hr-automation\ndescription: \"Automate Breezy HR tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Breezy HR Automation via Rube MCP\n\nAutomate Breezy HR operations through Composio's Breezy HR toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/breezy_hr](https://composio.dev/toolkits/breezy_hr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Breezy HR connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `breezy_hr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `breezy_hr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Breezy HR operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Breezy HR task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"breezy_hr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Breezy HR-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `breezy_hr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brex-automation/SKILL.md",
    "content": "---\nname: brex-automation\ndescription: \"Automate Brex tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brex Automation via Rube MCP\n\nAutomate Brex operations through Composio's Brex toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brex](https://composio.dev/toolkits/brex)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brex connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brex`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brex`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brex operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brex task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brex\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brex-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brex` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brex-staging-automation/SKILL.md",
    "content": "---\nname: brex-staging-automation\ndescription: \"Automate Brex Staging tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brex Staging Automation via Rube MCP\n\nAutomate Brex Staging operations through Composio's Brex Staging toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brex_staging](https://composio.dev/toolkits/brex_staging)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brex Staging connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brex_staging`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brex_staging`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brex Staging operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brex Staging task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brex_staging\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brex Staging-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brex_staging` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brightdata-automation/SKILL.md",
    "content": "---\nname: brightdata-automation\ndescription: \"Automate Brightdata tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brightdata Automation via Rube MCP\n\nAutomate Brightdata operations through Composio's Brightdata toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brightdata](https://composio.dev/toolkits/brightdata)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brightdata connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brightdata`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brightdata`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brightdata operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brightdata task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brightdata\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brightdata-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brightdata` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brightpearl-automation/SKILL.md",
    "content": "---\nname: brightpearl-automation\ndescription: \"Automate Brightpearl tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brightpearl Automation via Rube MCP\n\nAutomate Brightpearl operations through Composio's Brightpearl toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brightpearl](https://composio.dev/toolkits/brightpearl)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brightpearl connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brightpearl`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brightpearl`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brightpearl operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brightpearl task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brightpearl\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brightpearl-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brightpearl` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/brilliant-directories-automation/SKILL.md",
    "content": "---\nname: brilliant-directories-automation\ndescription: \"Automate Brilliant Directories tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Brilliant Directories Automation via Rube MCP\n\nAutomate Brilliant Directories operations through Composio's Brilliant Directories toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/brilliant_directories](https://composio.dev/toolkits/brilliant_directories)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Brilliant Directories connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `brilliant_directories`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `brilliant_directories`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Brilliant Directories operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Brilliant Directories task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"brilliant_directories\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Brilliant Directories-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `brilliant_directories` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/browseai-automation/SKILL.md",
    "content": "---\nname: browseai-automation\ndescription: \"Automate Browseai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Browseai Automation via Rube MCP\n\nAutomate Browseai operations through Composio's Browseai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/browseai](https://composio.dev/toolkits/browseai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Browseai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `browseai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `browseai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Browseai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Browseai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"browseai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Browseai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `browseai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/browser-tool-automation/SKILL.md",
    "content": "---\nname: browser-tool-automation\ndescription: \"Automate Browser Tool tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Browser Tool Automation via Rube MCP\n\nAutomate Browser Tool operations through Composio's Browser Tool toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/browser_tool](https://composio.dev/toolkits/browser_tool)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Browser Tool connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `browser_tool`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `browser_tool`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Browser Tool operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Browser Tool task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"browser_tool\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Browser Tool-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `browser_tool` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/browserbase-tool-automation/SKILL.md",
    "content": "---\nname: browserbase-tool-automation\ndescription: \"Automate Browserbase Tool tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Browserbase Tool Automation via Rube MCP\n\nAutomate Browserbase Tool operations through Composio's Browserbase Tool toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/browserbase_tool](https://composio.dev/toolkits/browserbase_tool)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Browserbase Tool connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `browserbase_tool`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `browserbase_tool`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Browserbase Tool operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Browserbase Tool task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"browserbase_tool\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Browserbase Tool-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `browserbase_tool` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/browserhub-automation/SKILL.md",
    "content": "---\nname: browserhub-automation\ndescription: \"Automate Browserhub tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Browserhub Automation via Rube MCP\n\nAutomate Browserhub operations through Composio's Browserhub toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/browserhub](https://composio.dev/toolkits/browserhub)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Browserhub connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `browserhub`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `browserhub`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Browserhub operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Browserhub task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"browserhub\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Browserhub-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `browserhub` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/browserless-automation/SKILL.md",
    "content": "---\nname: browserless-automation\ndescription: \"Automate Browserless tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Browserless Automation via Rube MCP\n\nAutomate Browserless operations through Composio's Browserless toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/browserless](https://composio.dev/toolkits/browserless)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Browserless connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `browserless`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `browserless`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Browserless operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Browserless task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"browserless\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Browserless-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `browserless` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/btcpay-server-automation/SKILL.md",
    "content": "---\nname: btcpay-server-automation\ndescription: \"Automate Btcpay Server tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Btcpay Server Automation via Rube MCP\n\nAutomate Btcpay Server operations through Composio's Btcpay Server toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/btcpay_server](https://composio.dev/toolkits/btcpay_server)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Btcpay Server connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `btcpay_server`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `btcpay_server`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Btcpay Server operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Btcpay Server task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"btcpay_server\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Btcpay Server-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `btcpay_server` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bubble-automation/SKILL.md",
    "content": "---\nname: bubble-automation\ndescription: \"Automate Bubble tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bubble Automation via Rube MCP\n\nAutomate Bubble operations through Composio's Bubble toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bubble](https://composio.dev/toolkits/bubble)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bubble connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bubble`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bubble`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bubble operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bubble task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bubble\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bubble-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bubble` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bugbug-automation/SKILL.md",
    "content": "---\nname: bugbug-automation\ndescription: \"Automate Bugbug tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bugbug Automation via Rube MCP\n\nAutomate Bugbug operations through Composio's Bugbug toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bugbug](https://composio.dev/toolkits/bugbug)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bugbug connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bugbug`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bugbug`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bugbug operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bugbug task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bugbug\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bugbug-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bugbug` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bugherd-automation/SKILL.md",
    "content": "---\nname: bugherd-automation\ndescription: \"Automate Bugherd tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bugherd Automation via Rube MCP\n\nAutomate Bugherd operations through Composio's Bugherd toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bugherd](https://composio.dev/toolkits/bugherd)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bugherd connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bugherd`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bugherd`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bugherd operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bugherd task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bugherd\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bugherd-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bugherd` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bugsnag-automation/SKILL.md",
    "content": "---\nname: bugsnag-automation\ndescription: \"Automate Bugsnag tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bugsnag Automation via Rube MCP\n\nAutomate Bugsnag operations through Composio's Bugsnag toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bugsnag](https://composio.dev/toolkits/bugsnag)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bugsnag connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bugsnag`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bugsnag`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bugsnag operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bugsnag task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bugsnag\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bugsnag-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bugsnag` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/buildkite-automation/SKILL.md",
    "content": "---\nname: buildkite-automation\ndescription: \"Automate Buildkite tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Buildkite Automation via Rube MCP\n\nAutomate Buildkite operations through Composio's Buildkite toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/buildkite](https://composio.dev/toolkits/buildkite)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Buildkite connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `buildkite`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `buildkite`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Buildkite operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Buildkite task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"buildkite\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Buildkite-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `buildkite` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/builtwith-automation/SKILL.md",
    "content": "---\nname: builtwith-automation\ndescription: \"Automate Builtwith tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Builtwith Automation via Rube MCP\n\nAutomate Builtwith operations through Composio's Builtwith toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/builtwith](https://composio.dev/toolkits/builtwith)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Builtwith connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `builtwith`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `builtwith`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Builtwith operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Builtwith task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"builtwith\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Builtwith-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `builtwith` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/bunnycdn-automation/SKILL.md",
    "content": "---\nname: bunnycdn-automation\ndescription: \"Automate Bunnycdn tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Bunnycdn Automation via Rube MCP\n\nAutomate Bunnycdn operations through Composio's Bunnycdn toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/bunnycdn](https://composio.dev/toolkits/bunnycdn)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Bunnycdn connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `bunnycdn`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `bunnycdn`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Bunnycdn operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Bunnycdn task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"bunnycdn\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Bunnycdn-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `bunnycdn` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/byteforms-automation/SKILL.md",
    "content": "---\nname: byteforms-automation\ndescription: \"Automate Byteforms tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Byteforms Automation via Rube MCP\n\nAutomate Byteforms operations through Composio's Byteforms toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/byteforms](https://composio.dev/toolkits/byteforms)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Byteforms connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `byteforms`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `byteforms`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Byteforms operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Byteforms task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"byteforms\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Byteforms-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `byteforms` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cabinpanda-automation/SKILL.md",
    "content": "---\nname: cabinpanda-automation\ndescription: \"Automate Cabinpanda tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cabinpanda Automation via Rube MCP\n\nAutomate Cabinpanda operations through Composio's Cabinpanda toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cabinpanda](https://composio.dev/toolkits/cabinpanda)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cabinpanda connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cabinpanda`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cabinpanda`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cabinpanda operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cabinpanda task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cabinpanda\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cabinpanda-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cabinpanda` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cal-automation/SKILL.md",
    "content": "---\nname: cal-automation\ndescription: \"Automate Cal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cal Automation via Rube MCP\n\nAutomate Cal operations through Composio's Cal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cal](https://composio.dev/toolkits/cal)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cal`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cal`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cal\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cal` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/calendarhero-automation/SKILL.md",
    "content": "---\nname: calendarhero-automation\ndescription: \"Automate Calendarhero tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Calendarhero Automation via Rube MCP\n\nAutomate Calendarhero operations through Composio's Calendarhero toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/calendarhero](https://composio.dev/toolkits/calendarhero)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Calendarhero connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `calendarhero`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `calendarhero`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Calendarhero operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Calendarhero task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"calendarhero\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Calendarhero-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `calendarhero` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/callerapi-automation/SKILL.md",
    "content": "---\nname: callerapi-automation\ndescription: \"Automate Callerapi tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Callerapi Automation via Rube MCP\n\nAutomate Callerapi operations through Composio's Callerapi toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/callerapi](https://composio.dev/toolkits/callerapi)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Callerapi connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `callerapi`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `callerapi`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Callerapi operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Callerapi task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"callerapi\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Callerapi-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `callerapi` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/callingly-automation/SKILL.md",
    "content": "---\nname: callingly-automation\ndescription: \"Automate Callingly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Callingly Automation via Rube MCP\n\nAutomate Callingly operations through Composio's Callingly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/callingly](https://composio.dev/toolkits/callingly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Callingly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `callingly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `callingly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Callingly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Callingly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"callingly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Callingly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `callingly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/callpage-automation/SKILL.md",
    "content": "---\nname: callpage-automation\ndescription: \"Automate Callpage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Callpage Automation via Rube MCP\n\nAutomate Callpage operations through Composio's Callpage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/callpage](https://composio.dev/toolkits/callpage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Callpage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `callpage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `callpage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Callpage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Callpage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"callpage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Callpage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `callpage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/campaign-cleaner-automation/SKILL.md",
    "content": "---\nname: campaign-cleaner-automation\ndescription: \"Automate Campaign Cleaner tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Campaign Cleaner Automation via Rube MCP\n\nAutomate Campaign Cleaner operations through Composio's Campaign Cleaner toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/campaign_cleaner](https://composio.dev/toolkits/campaign_cleaner)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Campaign Cleaner connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `campaign_cleaner`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `campaign_cleaner`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Campaign Cleaner operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Campaign Cleaner task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"campaign_cleaner\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Campaign Cleaner-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `campaign_cleaner` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/campayn-automation/SKILL.md",
    "content": "---\nname: campayn-automation\ndescription: \"Automate Campayn tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Campayn Automation via Rube MCP\n\nAutomate Campayn operations through Composio's Campayn toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/campayn](https://composio.dev/toolkits/campayn)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Campayn connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `campayn`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `campayn`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Campayn operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Campayn task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"campayn\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Campayn-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `campayn` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/canny-automation/SKILL.md",
    "content": "---\nname: canny-automation\ndescription: \"Automate Canny tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Canny Automation via Rube MCP\n\nAutomate Canny operations through Composio's Canny toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/canny](https://composio.dev/toolkits/canny)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Canny connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `canny`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `canny`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Canny operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Canny task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"canny\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Canny-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `canny` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/canvas-automation/SKILL.md",
    "content": "---\nname: canvas-automation\ndescription: \"Automate Canvas tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Canvas Automation via Rube MCP\n\nAutomate Canvas operations through Composio's Canvas toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/canvas](https://composio.dev/toolkits/canvas)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Canvas connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `canvas`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `canvas`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Canvas operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Canvas task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"canvas\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Canvas-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `canvas` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/capsule-crm-automation/SKILL.md",
    "content": "---\nname: Capsule CRM Automation\ndescription: \"Automate Capsule CRM operations -- manage contacts (parties), run structured filter queries, track tasks and projects, log entries, and handle organizations -- using natural language through the Composio MCP integration.\"\ncategory: crm\nrequires:\n  mcp:\n    - rube\n---\n\n# Capsule CRM Automation\n\nManage your Capsule CRM -- create and update contacts, run powerful filter queries on parties/opportunities/cases, track tasks and projects, browse activity entries, and organize team relationships -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/capsule_crm](https://composio.dev/toolkits/capsule_crm)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Capsule CRM account when prompted (OAuth authentication).\n3. Start issuing natural language commands to manage your CRM.\n\n---\n\n## Core Workflows\n\n### 1. Run Structured Filter Queries\nQuery parties, opportunities, or cases (projects) with multiple filter conditions, operators, and sorting.\n\n**Tool:** `CAPSULE_CRM_RUN_FILTER_QUERY`\n\n**Example prompt:**\n> \"Find all Capsule CRM contacts in California tagged as 'VIP' sorted by name\"\n\n**Key parameters:**\n- `entity` (required) -- One of: `parties`, `opportunities`, `kases`\n- `filter` (required) -- Filter object with:\n  - `conditions` -- Array of conditions, each with:\n    - `field` -- Field name (e.g., \"name\", \"email\", \"state\", \"country\", \"tag\", \"owner\", \"jobTitle\", \"addedOn\")\n    - `operator` -- One of: \"is\", \"is not\", \"starts with\", \"ends with\", \"contains\", \"is greater than\", \"is less than\", \"is after\", \"is before\", \"is older than\", \"is within last\", \"is within next\"\n    - `value` -- Value to compare against\n  - `orderBy` -- Array of sort objects with `field` and `direction` (\"ascending\"/\"descending\")\n- `embed` -- Additional data to include in response\n- `page` / `perPage` -- Pagination (max 100 per page)\n\n**Important field notes:**\n- Address fields (`city`, `state`, `country`, `zip`) are top-level, NOT nested under \"address\"\n- Country must be an ISO 3166-1 alpha-2 code (e.g., \"US\", \"GB\", \"CA\")\n- Custom fields use `custom:{fieldId}` format\n- Organization fields use `org.` prefix (e.g., `org.name`, `org.tag`)\n\n---\n\n### 2. List and Manage Contacts (Parties)\nRetrieve all contacts with optional filtering by modification date and embedded related data.\n\n**Tool:** `CAPSULE_CRM_LIST_PARTIES`\n\n**Example prompt:**\n> \"List all Capsule CRM contacts modified since January 2025 with their tags and organizations\"\n\n**Key parameters:**\n- `since` -- ISO8601 date to filter contacts changed after this date\n- `embed` -- Additional data: \"tags\", \"fields\", \"organisation\", \"missingImportantFields\"\n- `page` / `perPage` -- Pagination (max 100 per page, default 50)\n\n---\n\n### 3. Create New Contacts\nAdd people or organizations to your Capsule CRM with full details including emails, phones, addresses, tags, and custom fields.\n\n**Tool:** `CAPSULE_CRM_CREATE_PARTY`\n\n**Example prompt:**\n> \"Create a new person in Capsule CRM: John Smith, VP of Sales at Acme Corp, john@acme.com\"\n\n**Key parameters:**\n- `type` (required) -- \"person\" or \"organisation\"\n- For persons: `firstName`, `lastName`, `jobTitle`, `title`\n- For organisations: `name`\n- `emailAddresses` -- Array of `{address, type}` objects\n- `phoneNumbers` -- Array of `{number, type}` objects\n- `addresses` -- Array of address objects with `street`, `city`, `state`, `country`, `zip`, `type` (Home/Postal/Office/Billing/Shipping)\n- `organisation` -- Link to org by `{id}` or `{name}` (creates if not found)\n- `tags` -- Array of tags by `{name}` or `{id}`\n- `fields` -- Custom field values with `{definition, value}`\n- `websites` -- Array of `{address, service, type}` objects\n- `owner` -- Assign owner user `{id}`\n\n---\n\n### 4. Update Existing Contacts\nModify any aspect of a party record including adding/removing emails, phones, tags, and custom fields.\n\n**Tool:** `CAPSULE_CRM_UPDATE_PARTY`\n\n**Example prompt:**\n> \"Update Capsule CRM party 11587: add a work email john.new@acme.com and remove tag 'prospect'\"\n\n**Key parameters:**\n- `partyId` (required) -- Integer ID of the party to update\n- `party` (required) -- Object with fields to update. Supports:\n  - All creation fields (name, emails, phones, addresses, etc.)\n  - `_delete: true` on sub-items to remove them (requires the item's `id`)\n  - Tags: add by `{name}` or remove with `{id, _delete: true}`\n\n---\n\n### 5. Track Tasks\nList tasks with filtering by status and embedded related data.\n\n**Tool:** `CAPSULE_CRM_LIST_TASKS`\n\n**Example prompt:**\n> \"Show all open tasks in Capsule CRM with their linked parties and owners\"\n\n**Key parameters:**\n- `status` -- Filter by status: \"open\", \"completed\", \"pending\" (array)\n- `embed` -- Additional data: \"party\", \"opportunity\", \"kase\", \"owner\", \"nextTask\"\n- `page` / `perPage` -- Pagination (max 100 per page, default 50)\n\n---\n\n### 6. Browse Projects and Activity Entries\nList projects (cases) and recent activity entries including notes, emails, and completed tasks.\n\n**Tools:** `CAPSULE_CRM_LIST_PROJECTS`, `CAPSULE_CRM_LIST_ENTRIES_BY_DATE`\n\n**Example prompt:**\n> \"Show all open projects in Capsule CRM\" / \"Show recent activity entries with party details\"\n\n**Key parameters for projects:**\n- `status` -- Filter by \"OPEN\" or \"CLOSED\"\n- `search` -- Search term for project names/descriptions\n- `since` -- ISO8601 date for modifications after this date\n- `embed` -- \"tags,fields,party,opportunity,missingImportantFields\"\n\n**Key parameters for entries:**\n- `embed` -- \"party\", \"kase\", \"opportunity\", \"creator\", \"activityType\"\n- `page` / `perPage` -- Pagination (max 100 per page)\n\n---\n\n## Known Pitfalls\n\n- **Address fields are top-level**: When filtering, use `state`, `city`, `country`, `zip` directly -- NOT `address.state` or nested syntax.\n- **Country codes are ISO alpha-2**: Filter by \"US\", \"GB\", \"CA\" -- not \"United States\" or \"United Kingdom\".\n- **Custom fields use special syntax**: Reference custom fields as `custom:{fieldId}` in filter conditions. For org-level custom fields, use `org.custom:{fieldId}`.\n- **Projects are called \"kases\" in the API**: Despite being \"projects\" in the UI, the API entity type is `kases`. Use `kases` in filter queries.\n- **Delete operations require item IDs**: When updating a party to remove sub-items (emails, phones, tags), you must include the item's `id` along with `_delete: true`. List the party first to get sub-item IDs.\n- **Pagination defaults to 50**: All list endpoints default to 50 items per page with a max of 100. Always implement pagination for complete data retrieval.\n- **Embed values vary by entity**: Not all embed options work for all entities. Check the documentation for supported embed values per endpoint.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| Run filter query | `CAPSULE_CRM_RUN_FILTER_QUERY` | `entity`, `filter` |\n| List contacts | `CAPSULE_CRM_LIST_PARTIES` | None (optional filters) |\n| Create contact | `CAPSULE_CRM_CREATE_PARTY` | `type` |\n| Update contact | `CAPSULE_CRM_UPDATE_PARTY` | `partyId`, `party` |\n| Delete contact | `CAPSULE_CRM_DELETE_PARTY` | `party_id` |\n| List tasks | `CAPSULE_CRM_LIST_TASKS` | None (optional filters) |\n| List projects | `CAPSULE_CRM_LIST_PROJECTS` | None (optional filters) |\n| List activity entries | `CAPSULE_CRM_LIST_ENTRIES_BY_DATE` | None (optional filters) |\n| List org employees | `CAPSULE_CRM_LIST_ORG_EMPLOYEES` | Organisation ID |\n| List deleted opportunities | `CAPSULE_CRM_LIST_DELETED_OPPORTUNITIES` | `since` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/capsule_crm-automation/SKILL.md",
    "content": "---\nname: capsule_crm-automation\ndescription: \"Automate Capsule CRM tasks via Rube MCP (Composio): contacts, opportunities, cases, tasks, and pipeline management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Capsule CRM Automation via Rube MCP\n\nAutomate Capsule CRM operations through Composio's Capsule CRM toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/capsule_crm](https://composio.dev/toolkits/capsule_crm)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Capsule CRM connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `capsule_crm`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `capsule_crm`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"contacts, opportunities, cases, tasks, and pipeline management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Capsule CRM\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Capsule CRM Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Capsule CRM tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Capsule CRM Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Capsule CRM operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Capsule CRM connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Capsule CRM-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `capsule_crm` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/capsule_crm](https://composio.dev/toolkits/capsule_crm)\n"
  },
  {
    "path": "composio-skills/carbone-automation/SKILL.md",
    "content": "---\nname: carbone-automation\ndescription: \"Automate Carbone tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Carbone Automation via Rube MCP\n\nAutomate Carbone operations through Composio's Carbone toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/carbone](https://composio.dev/toolkits/carbone)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Carbone connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `carbone`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `carbone`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Carbone operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Carbone task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"carbone\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Carbone-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `carbone` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cardly-automation/SKILL.md",
    "content": "---\nname: cardly-automation\ndescription: \"Automate Cardly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cardly Automation via Rube MCP\n\nAutomate Cardly operations through Composio's Cardly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cardly](https://composio.dev/toolkits/cardly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cardly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cardly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cardly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cardly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cardly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cardly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cardly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cardly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/castingwords-automation/SKILL.md",
    "content": "---\nname: castingwords-automation\ndescription: \"Automate Castingwords tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Castingwords Automation via Rube MCP\n\nAutomate Castingwords operations through Composio's Castingwords toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/castingwords](https://composio.dev/toolkits/castingwords)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Castingwords connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `castingwords`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `castingwords`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Castingwords operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Castingwords task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"castingwords\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Castingwords-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `castingwords` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cats-automation/SKILL.md",
    "content": "---\nname: cats-automation\ndescription: \"Automate Cats tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cats Automation via Rube MCP\n\nAutomate Cats operations through Composio's Cats toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cats](https://composio.dev/toolkits/cats)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cats connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cats`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cats`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cats operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cats task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cats\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cats-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cats` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cdr-platform-automation/SKILL.md",
    "content": "---\nname: cdr-platform-automation\ndescription: \"Automate Cdr Platform tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cdr Platform Automation via Rube MCP\n\nAutomate Cdr Platform operations through Composio's Cdr Platform toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cdr_platform](https://composio.dev/toolkits/cdr_platform)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cdr Platform connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cdr_platform`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cdr_platform`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cdr Platform operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cdr Platform task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cdr_platform\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cdr Platform-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cdr_platform` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/census-bureau-automation/SKILL.md",
    "content": "---\nname: census-bureau-automation\ndescription: \"Automate Census Bureau tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Census Bureau Automation via Rube MCP\n\nAutomate Census Bureau operations through Composio's Census Bureau toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/census_bureau](https://composio.dev/toolkits/census_bureau)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Census Bureau connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `census_bureau`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `census_bureau`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Census Bureau operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Census Bureau task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"census_bureau\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Census Bureau-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `census_bureau` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/centralstationcrm-automation/SKILL.md",
    "content": "---\nname: centralstationcrm-automation\ndescription: \"Automate Centralstationcrm tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Centralstationcrm Automation via Rube MCP\n\nAutomate Centralstationcrm operations through Composio's Centralstationcrm toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/centralstationcrm](https://composio.dev/toolkits/centralstationcrm)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Centralstationcrm connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `centralstationcrm`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `centralstationcrm`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Centralstationcrm operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Centralstationcrm task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"centralstationcrm\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Centralstationcrm-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `centralstationcrm` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/certifier-automation/SKILL.md",
    "content": "---\nname: certifier-automation\ndescription: \"Automate Certifier tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Certifier Automation via Rube MCP\n\nAutomate Certifier operations through Composio's Certifier toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/certifier](https://composio.dev/toolkits/certifier)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Certifier connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `certifier`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `certifier`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Certifier operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Certifier task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"certifier\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Certifier-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `certifier` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/chaser-automation/SKILL.md",
    "content": "---\nname: chaser-automation\ndescription: \"Automate Chaser tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Chaser Automation via Rube MCP\n\nAutomate Chaser operations through Composio's Chaser toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/chaser](https://composio.dev/toolkits/chaser)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Chaser connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `chaser`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `chaser`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Chaser operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Chaser task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"chaser\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Chaser-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `chaser` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/chatbotkit-automation/SKILL.md",
    "content": "---\nname: chatbotkit-automation\ndescription: \"Automate Chatbotkit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Chatbotkit Automation via Rube MCP\n\nAutomate Chatbotkit operations through Composio's Chatbotkit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/chatbotkit](https://composio.dev/toolkits/chatbotkit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Chatbotkit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `chatbotkit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `chatbotkit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Chatbotkit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Chatbotkit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"chatbotkit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Chatbotkit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `chatbotkit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/chatfai-automation/SKILL.md",
    "content": "---\nname: chatfai-automation\ndescription: \"Automate Chatfai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Chatfai Automation via Rube MCP\n\nAutomate Chatfai operations through Composio's Chatfai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/chatfai](https://composio.dev/toolkits/chatfai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Chatfai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `chatfai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `chatfai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Chatfai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Chatfai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"chatfai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Chatfai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `chatfai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/chatwork-automation/SKILL.md",
    "content": "---\nname: chatwork-automation\ndescription: \"Automate Chatwork tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Chatwork Automation via Rube MCP\n\nAutomate Chatwork operations through Composio's Chatwork toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/chatwork](https://composio.dev/toolkits/chatwork)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Chatwork connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `chatwork`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `chatwork`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Chatwork operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Chatwork task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"chatwork\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Chatwork-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `chatwork` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/chmeetings-automation/SKILL.md",
    "content": "---\nname: chmeetings-automation\ndescription: \"Automate Chmeetings tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Chmeetings Automation via Rube MCP\n\nAutomate Chmeetings operations through Composio's Chmeetings toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/chmeetings](https://composio.dev/toolkits/chmeetings)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Chmeetings connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `chmeetings`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `chmeetings`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Chmeetings operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Chmeetings task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"chmeetings\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Chmeetings-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `chmeetings` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cincopa-automation/SKILL.md",
    "content": "---\nname: cincopa-automation\ndescription: \"Automate Cincopa tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cincopa Automation via Rube MCP\n\nAutomate Cincopa operations through Composio's Cincopa toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cincopa](https://composio.dev/toolkits/cincopa)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cincopa connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cincopa`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cincopa`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cincopa operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cincopa task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cincopa\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cincopa-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cincopa` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/claid-ai-automation/SKILL.md",
    "content": "---\nname: claid-ai-automation\ndescription: \"Automate Claid AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Claid AI Automation via Rube MCP\n\nAutomate Claid AI operations through Composio's Claid AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/claid_ai](https://composio.dev/toolkits/claid_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Claid AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `claid_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `claid_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Claid AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Claid AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"claid_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Claid AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `claid_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/classmarker-automation/SKILL.md",
    "content": "---\nname: classmarker-automation\ndescription: \"Automate Classmarker tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Classmarker Automation via Rube MCP\n\nAutomate Classmarker operations through Composio's Classmarker toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/classmarker](https://composio.dev/toolkits/classmarker)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Classmarker connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `classmarker`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `classmarker`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Classmarker operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Classmarker task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"classmarker\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Classmarker-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `classmarker` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/clearout-automation/SKILL.md",
    "content": "---\nname: clearout-automation\ndescription: \"Automate Clearout tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Clearout Automation via Rube MCP\n\nAutomate Clearout operations through Composio's Clearout toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/clearout](https://composio.dev/toolkits/clearout)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Clearout connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `clearout`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `clearout`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Clearout operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Clearout task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"clearout\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Clearout-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `clearout` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/clickmeeting-automation/SKILL.md",
    "content": "---\nname: clickmeeting-automation\ndescription: \"Automate Clickmeeting tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Clickmeeting Automation via Rube MCP\n\nAutomate Clickmeeting operations through Composio's Clickmeeting toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/clickmeeting](https://composio.dev/toolkits/clickmeeting)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Clickmeeting connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `clickmeeting`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `clickmeeting`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Clickmeeting operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Clickmeeting task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"clickmeeting\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Clickmeeting-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `clickmeeting` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/clockify-automation/SKILL.md",
    "content": "---\nname: Clockify Automation\ndescription: \"Automate time tracking workflows in Clockify -- create and manage time entries, workspaces, and users through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Clockify Automation\n\nAutomate your Clockify time tracking operations directly from Claude Code. Log time entries, query historical data, manage workspaces, and audit team activity -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/clockify](https://composio.dev/toolkits/clockify)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Clockify account through the connection link provided\n3. Start automating your time tracking workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Create Time Entries\n\nLog time with project, task, and tag associations, plus billable status.\n\n**Tool:** `CLOCKIFY_CREATE_TIME_ENTRY`\n\n```\nLog 2 hours of work on project 64a687e2 in workspace 64a687e3 starting at 9am UTC today with description \"API development\"\n```\n\nKey parameters:\n- `workspaceId` (required) -- workspace where the entry is created\n- `start` (required) -- ISO 8601 start time (e.g., `2026-02-11T09:00:00Z`)\n- `end` -- ISO 8601 end time; omit to create a running timer\n- `projectId` -- associate with a project\n- `taskId` -- associate with a task\n- `description` -- work description (0-3000 chars)\n- `tagIds` -- array of tag IDs\n- `billable` -- whether the entry is billable\n- `customFieldValues` -- array of custom field entries with `customFieldId` and `value`\n\n### 2. Query Time Entries\n\nRetrieve historical time entries for reporting, auditing, and invoicing.\n\n**Tool:** `CLOCKIFY_GET_TIME_ENTRIES`\n\n```\nGet all time entries for user abc123 in workspace xyz789 from January 2026\n```\n\nKey parameters:\n- `workspaceId` (required) -- workspace to query\n- `userId` (required) -- user whose entries to retrieve\n- `start` / `end` -- ISO 8601 date range filters\n- `project` -- filter by project ID\n- `task` -- filter by task ID\n- `tags` -- comma-separated tag IDs\n- `description` -- text filter (partial match)\n- `hydrated` -- set `true` to get full project/task/tag objects instead of just IDs\n- `in-progress` -- set `true` to return only the running timer\n- `page` / `page-size` -- pagination (default 50 per page)\n\n### 3. Delete Time Entries\n\nRemove erroneous, duplicate, or cancelled time entries.\n\n**Tool:** `CLOCKIFY_DELETE_TIME_ENTRY`\n\n```\nDelete time entry 5b715448 from workspace 64a687e3\n```\n\n- Requires `workspaceId` and `id` (the time entry ID)\n- Use for cleanup of bad imports or duplicates\n\n### 4. Manage Workspaces\n\nList all workspaces the authenticated user belongs to.\n\n**Tool:** `CLOCKIFY_GET_ALL_MY_WORKSPACES`\n\n```\nShow me all my Clockify workspaces\n```\n\n- Optional `roles` filter -- array of roles like `[\"WORKSPACE_ADMIN\", \"OWNER\"]`\n- Use this to discover workspace IDs before creating or querying entries\n\n### 5. User Information\n\nRetrieve current user details and list workspace members.\n\n**Tools:** `CLOCKIFY_GET_CURRENTLY_LOGGED_IN_USER_INFO`, `CLOCKIFY_FIND_ALL_USERS_ON_WORKSPACE`\n\n```\nWho am I logged in as? Then list all users in workspace 64a687e3\n```\n\n- `CLOCKIFY_GET_CURRENTLY_LOGGED_IN_USER_INFO` returns the authenticated user's profile (no parameters needed)\n- `CLOCKIFY_FIND_ALL_USERS_ON_WORKSPACE` requires `workspaceId`; supports `name`, `email` filters and pagination (`page`, `page-size` max 100)\n\n### 6. Running Timer Management\n\nStart a timer by omitting `end` in create, or check for running entries.\n\n**Tools:** `CLOCKIFY_CREATE_TIME_ENTRY`, `CLOCKIFY_GET_TIME_ENTRIES`\n\n```\nStart a timer on project abc in workspace xyz with description \"Working on bug fix\"\n```\n\n- Create without `end` to start a running timer\n- Use `CLOCKIFY_GET_TIME_ENTRIES` with `in-progress: true` to check if a timer is running\n\n---\n\n## Known Pitfalls\n\n- **Workspace and user IDs are required:** Most Clockify tools require both `workspaceId` and `userId`. Always call `CLOCKIFY_GET_ALL_MY_WORKSPACES` and `CLOCKIFY_GET_CURRENTLY_LOGGED_IN_USER_INFO` first to resolve these IDs.\n- **ISO 8601 timestamps:** All time parameters must be in ISO 8601 format with timezone (e.g., `2026-02-11T09:00:00Z`). Omitting the timezone causes unpredictable behavior.\n- **Running timers:** Only one timer can run at a time. Creating a new entry without `end` will fail if another timer is already active. Stop the existing timer first.\n- **Pagination defaults:** `CLOCKIFY_GET_TIME_ENTRIES` defaults to 50 entries per page. For full exports, loop through pages until no more results are returned.\n- **Tag IDs are workspace-scoped:** Tag IDs from one workspace cannot be used in another. Always resolve tags within the target workspace context.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `CLOCKIFY_CREATE_TIME_ENTRY` | Create a time entry or start a timer (requires `workspaceId`, `start`) |\n| `CLOCKIFY_GET_TIME_ENTRIES` | List time entries with filters (requires `workspaceId`, `userId`) |\n| `CLOCKIFY_DELETE_TIME_ENTRY` | Delete a time entry (requires `workspaceId`, `id`) |\n| `CLOCKIFY_GET_ALL_MY_WORKSPACES` | List all workspaces for the authenticated user |\n| `CLOCKIFY_GET_CURRENTLY_LOGGED_IN_USER_INFO` | Get current user profile info |\n| `CLOCKIFY_FIND_ALL_USERS_ON_WORKSPACE` | List all users in a workspace (requires `workspaceId`) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudcart-automation/SKILL.md",
    "content": "---\nname: cloudcart-automation\ndescription: \"Automate Cloudcart tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudcart Automation via Rube MCP\n\nAutomate Cloudcart operations through Composio's Cloudcart toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudcart](https://composio.dev/toolkits/cloudcart)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudcart connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudcart`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudcart`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudcart operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudcart task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudcart\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudcart-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudcart` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudconvert-automation/SKILL.md",
    "content": "---\nname: cloudconvert-automation\ndescription: \"Automate Cloudconvert tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudconvert Automation via Rube MCP\n\nAutomate Cloudconvert operations through Composio's Cloudconvert toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudconvert](https://composio.dev/toolkits/cloudconvert)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudconvert connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudconvert`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudconvert`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudconvert operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudconvert task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudconvert\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudconvert-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudconvert` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudflare-api-key-automation/SKILL.md",
    "content": "---\nname: cloudflare-api-key-automation\ndescription: \"Automate Cloudflare API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudflare API Automation via Rube MCP\n\nAutomate Cloudflare API operations through Composio's Cloudflare API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudflare_api_key](https://composio.dev/toolkits/cloudflare_api_key)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudflare API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_api_key`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_api_key`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudflare API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudflare API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudflare_api_key\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudflare API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_api_key` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudflare-automation/SKILL.md",
    "content": "---\nname: cloudflare-automation\ndescription: \"Automate Cloudflare tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudflare Automation via Rube MCP\n\nAutomate Cloudflare operations through Composio's Cloudflare toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudflare](https://composio.dev/toolkits/cloudflare)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudflare connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudflare operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudflare task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudflare\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudflare-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudflare-browser-rendering-automation/SKILL.md",
    "content": "---\nname: cloudflare-browser-rendering-automation\ndescription: \"Automate Cloudflare Browser Rendering tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudflare Browser Rendering Automation via Rube MCP\n\nAutomate Cloudflare Browser Rendering operations through Composio's Cloudflare Browser Rendering toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudflare_browser_rendering](https://composio.dev/toolkits/cloudflare_browser_rendering)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudflare Browser Rendering connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_browser_rendering`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_browser_rendering`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudflare Browser Rendering operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudflare Browser Rendering task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudflare_browser_rendering\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudflare Browser Rendering-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudflare_browser_rendering` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudinary-automation/SKILL.md",
    "content": "---\nname: Cloudinary Automation\ndescription: \"Automate Cloudinary media management including folder organization, upload presets, asset lookup, transformations, and usage monitoring through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Cloudinary Automation\n\nAutomate Cloudinary media management workflows -- create folders, configure upload presets, look up assets, manage transformations, search folders, and monitor usage -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/cloudinary](https://composio.dev/toolkits/cloudinary)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Cloudinary account when prompted (API key auth via Composio)\n3. Start issuing natural language commands for Cloudinary automation\n\n---\n\n## Core Workflows\n\n### 1. Organize Assets with Folders\n\nCreate folder structures for organizing hosted images, videos, and raw files.\n\n**Tool:** `CLOUDINARY_CREATE_FOLDER`\n\nKey parameters:\n- `folder` -- full path of the new asset folder (required), e.g., `images/events/2023`\n\nSupporting tools:\n- `CLOUDINARY_SEARCH_FOLDERS` -- search folders by name, path, or creation date using Lucene-like expressions\n  - `expression` -- search filter (e.g., `name:sample AND path:events`)\n  - `max_results` -- 1-500 results (default 50)\n  - `sort_by` -- list of sort objects (e.g., `[{\"created_at\": \"desc\"}]`)\n  - `next_cursor` -- pagination cursor\n- `CLOUDINARY_GET_RESOURCES_BY_ASSET_FOLDER` -- list assets within a specific folder\n\nExample prompt:\n> \"Create a folder called 'marketing/campaigns/spring-2026' in Cloudinary\"\n\n---\n\n### 2. Configure Upload Presets\n\nDefine centralized upload behavior including target folder, allowed formats, transformations, tags, and overwrite rules.\n\n**Tool:** `CLOUDINARY_CREATE_UPLOAD_PRESET`\n\nKey parameters:\n- `name` -- preset name (auto-generated if omitted)\n- `folder` -- target folder path for uploads (e.g., `samples/`)\n- `allowed_formats` -- comma-separated list (e.g., `jpg,png,webp`)\n- `tags` -- comma-separated tags to apply (e.g., `marketing,thumbnail`)\n- `transformation` -- incoming transformation (e.g., `c_limit,w_500`)\n- `eager` -- eager transformations to generate on upload (e.g., `c_fill,g_face,h_150,w_150`)\n- `unsigned` -- allow unsigned uploads (`true`/`false`)\n- `overwrite` -- overwrite existing assets with same public_id (cannot be `true` when `unsigned=true`)\n- `resource_type` -- `image`, `video`, or `raw` (default `image`)\n- `unique_filename` -- append random suffix to avoid collisions (default `true`)\n- `use_filename` -- use original filename (default `false`)\n- `moderation` -- moderation type: `manual`, `webpurify`, `aws_rek`, etc.\n- `auto_tagging` -- confidence threshold 0.0-1.0 for AI auto-tagging\n- `notification_url` -- webhook URL for upload notifications\n\nExample prompt:\n> \"Create an upload preset called 'product-images' that only allows JPG and PNG, stores in 'products/' folder, and auto-tags with 0.7 confidence\"\n\n---\n\n### 3. Look Up Asset Details\n\nRetrieve full details for a specific asset by its public ID, including metadata, derived assets, and related resources.\n\n**Tool:** `CLOUDINARY_GET_RESOURCE_BY_PUBLIC_ID`\n\nKey parameters:\n- `public_id` -- the asset's public ID (required)\n- `resource_type` -- `image`, `video`, or `raw` (required)\n- `type` -- delivery type: `upload`, `private`, `authenticated`, `fetch`, etc. (required)\n- `colors` -- include color histogram and predominant colors\n- `faces` -- include detected face coordinates\n- `media_metadata` -- include IPTC, XMP, and detailed metadata\n- `quality_analysis` -- include quality analysis scores\n- `phash` -- include perceptual hash for similarity detection\n- `versions` -- include backed-up versions\n- `related` -- include related assets\n- `max_results` -- max derived/related assets to return (1-500)\n\nExample prompt:\n> \"Get full details for the image 'products/hero-banner' including color analysis and quality scores\"\n\n---\n\n### 4. Manage Transformations and Derived Assets\n\nList existing transformations, apply eager transformations to uploaded assets, and clean up derived resources.\n\n**Tools:**\n- `CLOUDINARY_GET_TRANSFORMATIONS` -- list all named and unnamed transformations\n  - `max_results` -- 1-500 (default 10)\n  - `next_cursor` -- pagination cursor\n- `CLOUDINARY_EXPLICIT_RESOURCE` -- update an existing asset: pre-generate transformations, update metadata, move to new folders, or modify tags\n  - `public_id` -- target asset (required)\n  - `eager` -- list of transformation strings to pre-generate (e.g., `[\"c_fill,w_300,h_200\", \"c_thumb,w_100,h_100,g_face\"]`)\n  - `eager_async` -- generate transformations asynchronously\n  - `tags` -- replace existing tags\n  - `asset_folder` -- move asset to a new folder\n  - `display_name` -- set display name\n  - `context` -- key-value metadata (e.g., `{\"alt\": \"Mountain view\"}`)\n  - `invalidate` -- invalidate CDN cache (takes up to 1 hour)\n- `CLOUDINARY_DELETE_DERIVED_RESOURCES` -- delete specific derived assets by IDs (up to 100 per call)\n\nExample prompt:\n> \"Pre-generate a 300x200 fill crop and a 100x100 face-detection thumbnail for asset 'products/hero-banner'\"\n\n---\n\n### 5. Monitor Usage and Configuration\n\nCheck account-level usage limits, environment configuration, and tag inventory.\n\n**Tools:**\n- `CLOUDINARY_GET_USAGE` -- monitor storage, bandwidth, requests, and quota limits\n- `CLOUDINARY_GET_CONFIG` -- fetch environment config details\n  - `settings` -- set to `true` to include configuration settings like `folder_mode`\n- `CLOUDINARY_GET_TAGS` -- list all tags for a resource type\n\nExample prompt:\n> \"Show me my Cloudinary account usage and remaining quota\"\n\n---\n\n### 6. Set Up Webhook Triggers\n\nCreate webhook notifications for specific Cloudinary events.\n\n**Tool:** `CLOUDINARY_CREATE_TRIGGER`\n\nUse to receive callbacks when uploads complete, transformations finish, or other events occur.\n\nExample prompt:\n> \"Create a webhook trigger that notifies https://my-app.com/hook on upload events\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Folder creation idempotency | `CLOUDINARY_CREATE_FOLDER` may error or no-op if the path already exists -- design idempotent folder naming |\n| Preset-upload alignment | Upload preset options like `allowed_formats`, `folder`, and `unsigned` must match the actual upload method or uploads will be rejected |\n| Strict asset lookup | `CLOUDINARY_GET_RESOURCE_BY_PUBLIC_ID` fails if any of `resource_type`, `type`, or `public_id` is incorrect, even when the asset exists |\n| Folder path sensitivity | `CLOUDINARY_GET_RESOURCES_BY_ASSET_FOLDER` only lists assets in the exact folder specified; typos return empty results |\n| Quota blocking | `CLOUDINARY_GET_USAGE` reflects account-level limits -- hitting caps silently blocks uploads until usage is checked and addressed |\n| CDN invalidation delay | Setting `invalidate=true` on `CLOUDINARY_EXPLICIT_RESOURCE` takes up to 1 hour to propagate |\n| Unsigned vs overwrite conflict | Cannot set `overwrite=true` when `unsigned=true` in upload presets |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| Create folder | `CLOUDINARY_CREATE_FOLDER` | `folder` |\n| Search folders | `CLOUDINARY_SEARCH_FOLDERS` | `expression`, `max_results` |\n| List folder assets | `CLOUDINARY_GET_RESOURCES_BY_ASSET_FOLDER` | folder path |\n| Create upload preset | `CLOUDINARY_CREATE_UPLOAD_PRESET` | `name`, `folder`, `allowed_formats`, `tags` |\n| Get asset details | `CLOUDINARY_GET_RESOURCE_BY_PUBLIC_ID` | `public_id`, `resource_type`, `type` |\n| List transformations | `CLOUDINARY_GET_TRANSFORMATIONS` | `max_results`, `next_cursor` |\n| Update/transform asset | `CLOUDINARY_EXPLICIT_RESOURCE` | `public_id`, `eager`, `tags` |\n| Delete derived assets | `CLOUDINARY_DELETE_DERIVED_RESOURCES` | `derived_resource_ids` |\n| Get usage | `CLOUDINARY_GET_USAGE` | (none) |\n| Get config | `CLOUDINARY_GET_CONFIG` | `settings` |\n| List tags | `CLOUDINARY_GET_TAGS` | resource_type |\n| Create webhook | `CLOUDINARY_CREATE_TRIGGER` | event type, URL |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudlayer-automation/SKILL.md",
    "content": "---\nname: cloudlayer-automation\ndescription: \"Automate Cloudlayer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudlayer Automation via Rube MCP\n\nAutomate Cloudlayer operations through Composio's Cloudlayer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudlayer](https://composio.dev/toolkits/cloudlayer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudlayer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudlayer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudlayer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudlayer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudlayer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudlayer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudlayer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudlayer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cloudpress-automation/SKILL.md",
    "content": "---\nname: cloudpress-automation\ndescription: \"Automate Cloudpress tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cloudpress Automation via Rube MCP\n\nAutomate Cloudpress operations through Composio's Cloudpress toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cloudpress](https://composio.dev/toolkits/cloudpress)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cloudpress connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudpress`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudpress`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cloudpress operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cloudpress task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cloudpress\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cloudpress-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cloudpress` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coassemble-automation/SKILL.md",
    "content": "---\nname: coassemble-automation\ndescription: \"Automate Coassemble tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Coassemble Automation via Rube MCP\n\nAutomate Coassemble operations through Composio's Coassemble toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/coassemble](https://composio.dev/toolkits/coassemble)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Coassemble connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `coassemble`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `coassemble`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Coassemble operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Coassemble task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"coassemble\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Coassemble-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `coassemble` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/codacy-automation/SKILL.md",
    "content": "---\nname: codacy-automation\ndescription: \"Automate Codacy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Codacy Automation via Rube MCP\n\nAutomate Codacy operations through Composio's Codacy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/codacy](https://composio.dev/toolkits/codacy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Codacy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `codacy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `codacy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Codacy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Codacy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"codacy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Codacy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `codacy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/codeinterpreter-automation/SKILL.md",
    "content": "---\nname: codeinterpreter-automation\ndescription: \"Automate Codeinterpreter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Codeinterpreter Automation via Rube MCP\n\nAutomate Codeinterpreter operations through Composio's Codeinterpreter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/codeinterpreter](https://composio.dev/toolkits/codeinterpreter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Codeinterpreter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `codeinterpreter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `codeinterpreter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Codeinterpreter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Codeinterpreter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"codeinterpreter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Codeinterpreter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `codeinterpreter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/codereadr-automation/SKILL.md",
    "content": "---\nname: codereadr-automation\ndescription: \"Automate Codereadr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Codereadr Automation via Rube MCP\n\nAutomate Codereadr operations through Composio's Codereadr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/codereadr](https://composio.dev/toolkits/codereadr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Codereadr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `codereadr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `codereadr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Codereadr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Codereadr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"codereadr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Codereadr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `codereadr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coinbase-automation/SKILL.md",
    "content": "---\nname: Coinbase Automation\ndescription: \"Coinbase Automation: list and manage cryptocurrency wallets, accounts, and portfolio data via Coinbase CDP SDK\"\nrequires:\n  mcp: [rube]\n---\n\n# Coinbase Automation\n\nAutomate Coinbase operations including listing cryptocurrency wallets, paginating through wallet collections, and retrieving portfolio data.\n\n**Toolkit docs:** [composio.dev/toolkits/coinbase](https://composio.dev/toolkits/coinbase)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `coinbase` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. List All Wallets\n\nRetrieve all wallets from Coinbase with pagination support.\n\n**Tool:** `COINBASE_LIST_WALLETS`\n\n**Key Parameters:**\n- `limit` -- Results per page (1--100, default: 25)\n- `order` -- Sort order: `\"asc\"` (ascending) or `\"desc\"` (descending, default)\n- `starting_after` -- Cursor for forward pagination: ID of the last wallet from the previous page\n- `ending_before` -- Cursor for backward pagination: ID of the first wallet from the previous page\n\n**Example (first page):**\n```\nTool: COINBASE_LIST_WALLETS\nArguments:\n  limit: 50\n  order: \"desc\"\n```\n\n**Example (next page):**\n```\nTool: COINBASE_LIST_WALLETS\nArguments:\n  limit: 50\n  order: \"desc\"\n  starting_after: \"wallet_abc123_last_id_from_prev_page\"\n```\n\n---\n\n### 2. Paginate Through All Wallets\n\nTo retrieve a complete wallet inventory, iterate through pages.\n\n**Steps:**\n1. Call `COINBASE_LIST_WALLETS` with desired `limit` and `order`\n2. If the response contains more results, note the ID of the last wallet returned\n3. Call `COINBASE_LIST_WALLETS` again with `starting_after` set to that last wallet ID\n4. Repeat until no more results are returned\n\n---\n\n### 3. Audit Wallet Portfolio\n\nRetrieve wallet data for portfolio analysis and reporting.\n\n**Steps:**\n1. Call `COINBASE_LIST_WALLETS` with `limit: 100` to maximize per-page results\n2. Collect wallet balances and metadata from each page\n3. Aggregate data across all pages for a complete portfolio view\n\n---\n\n### 4. Monitor Wallet Changes\n\nPeriodically list wallets to detect new additions or changes.\n\n**Steps:**\n1. Call `COINBASE_LIST_WALLETS` with `order: \"desc\"` to get newest wallets first\n2. Compare against previously stored wallet IDs to identify new entries\n3. Schedule periodic checks for continuous monitoring\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Pagination required** | Wallet lists are paginated. Always check for additional pages using cursor-based pagination (`starting_after`/`ending_before`). |\n| **Limit bounds** | The `limit` parameter accepts 1--100. Values outside this range cause errors. Default is 25. |\n| **Cursor-based pagination** | Uses wallet IDs as cursors, not page numbers. You must extract the last/first wallet ID from each response to navigate pages. |\n| **CDP SDK scope** | This tool uses the Coinbase CDP SDK. Available operations depend on the API key permissions granted during connection setup. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `COINBASE_LIST_WALLETS` | List cryptocurrency wallets with pagination |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coinmarketcal-automation/SKILL.md",
    "content": "---\nname: coinmarketcal-automation\ndescription: \"Automate Coinmarketcal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Coinmarketcal Automation via Rube MCP\n\nAutomate Coinmarketcal operations through Composio's Coinmarketcal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/coinmarketcal](https://composio.dev/toolkits/coinmarketcal)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Coinmarketcal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcal`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcal`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Coinmarketcal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Coinmarketcal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"coinmarketcal\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Coinmarketcal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcal` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coinmarketcap-automation/SKILL.md",
    "content": "---\nname: coinmarketcap-automation\ndescription: \"Automate Coinmarketcap tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Coinmarketcap Automation via Rube MCP\n\nAutomate Coinmarketcap operations through Composio's Coinmarketcap toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/coinmarketcap](https://composio.dev/toolkits/coinmarketcap)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Coinmarketcap connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcap`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcap`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Coinmarketcap operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Coinmarketcap task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"coinmarketcap\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Coinmarketcap-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `coinmarketcap` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coinranking-automation/SKILL.md",
    "content": "---\nname: coinranking-automation\ndescription: \"Automate Coinranking tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Coinranking Automation via Rube MCP\n\nAutomate Coinranking operations through Composio's Coinranking toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/coinranking](https://composio.dev/toolkits/coinranking)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Coinranking connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `coinranking`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `coinranking`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Coinranking operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Coinranking task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"coinranking\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Coinranking-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `coinranking` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/college-football-data-automation/SKILL.md",
    "content": "---\nname: college-football-data-automation\ndescription: \"Automate College Football Data tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# College Football Data Automation via Rube MCP\n\nAutomate College Football Data operations through Composio's College Football Data toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/college_football_data](https://composio.dev/toolkits/college_football_data)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active College Football Data connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `college_football_data`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `college_football_data`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"College Football Data operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific College Football Data task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"college_football_data\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with College Football Data-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `college_football_data` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/composio-automation/SKILL.md",
    "content": "---\nname: composio-automation\ndescription: \"Automate Composio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Composio Automation via Rube MCP\n\nAutomate Composio operations through Composio's Composio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/composio](https://composio.dev/toolkits/composio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Composio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `composio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `composio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Composio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Composio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"composio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Composio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `composio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/composio-search-automation/SKILL.md",
    "content": "---\nname: composio-search-automation\ndescription: \"Automate Composio Search tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Composio Search Automation via Rube MCP\n\nAutomate Composio Search operations through Composio's Composio Search toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/composio_search](https://composio.dev/toolkits/composio_search)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Composio Search connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `composio_search`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `composio_search`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Composio Search operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Composio Search task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"composio_search\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Composio Search-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `composio_search` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/connecteam-automation/SKILL.md",
    "content": "---\nname: connecteam-automation\ndescription: \"Automate Connecteam tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Connecteam Automation via Rube MCP\n\nAutomate Connecteam operations through Composio's Connecteam toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/connecteam](https://composio.dev/toolkits/connecteam)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Connecteam connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `connecteam`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `connecteam`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Connecteam operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Connecteam task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"connecteam\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Connecteam-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `connecteam` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/contentful-automation/SKILL.md",
    "content": "---\nname: Contentful Automation\ndescription: \"Automate headless CMS operations in Contentful -- list spaces, retrieve space metadata, and update space configurations through the Composio Contentful integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Contentful Automation\n\nManage your **Contentful** headless CMS spaces directly from Claude Code. List spaces, retrieve metadata, and update space configurations without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/contentful](https://composio.dev/toolkits/contentful)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Contentful account when prompted. The agent will provide an authentication link. Ensure your access token has space management scopes.\n\n---\n\n## Core Workflows\n\n### 1. List All Spaces\n\nDiscover all Contentful spaces accessible to your authenticated account. This is typically the first operation since most other actions require a `space_id`.\n\n**Tool:** `CONTENTFUL_LIST_SPACES`\n\nKey parameters:\n- `limit` (1-1000) -- maximum number of spaces to return (default: 100)\n- `skip` -- number of spaces to skip for pagination\n- `order` -- sort by field, e.g., `sys.createdAt` or `-sys.createdAt` for descending\n\nExample prompt: *\"List all my Contentful spaces\"*\n\n---\n\n### 2. Get Space Details\n\nRetrieve detailed metadata for a specific space including its current `sys.version`, which is required for updates.\n\n**Tool:** `CONTENTFUL_GET_SPACE`\n\nKey parameters:\n- `space_id` (required) -- the ID of the space to retrieve (alphanumeric, 1-64 chars)\n\nExample prompt: *\"Get details for Contentful space abc123def\"*\n\n---\n\n### 3. Update Space Name\n\nUpdate the name of a specific space. Requires the current version number for optimistic locking to prevent concurrent modification conflicts.\n\n**Tool:** `CONTENTFUL_UPDATE_SPACE`\n\nKey parameters:\n- `space_id` (required) -- ID of the space to update\n- `name` (required) -- new name for the space (1-255 chars)\n- `version` (required) -- current space version from `sys.version` (must be > 0)\n\nExample prompt: *\"Rename Contentful space abc123def to 'Production Content Hub'\"*\n\n---\n\n### 4. Audit Space Inventory\n\nCombine space listing and detail retrieval to audit your organization's Contentful spaces.\n\n**Tools:** `CONTENTFUL_LIST_SPACES` then `CONTENTFUL_GET_SPACE`\n\nWorkflow:\n1. List all spaces to get IDs and names\n2. Fetch details for each space to get version info, creation dates, and metadata\n\nExample prompt: *\"Audit all Contentful spaces -- list them with their creation dates and current versions\"*\n\n---\n\n## Known Pitfalls\n\n- **Version conflicts on update:** `CONTENTFUL_UPDATE_SPACE` requires the latest `sys.version` from `CONTENTFUL_GET_SPACE`. If someone else modified the space between your read and write, the update will fail with a version conflict. Always fetch the space immediately before updating.\n- **Pagination for many spaces:** `CONTENTFUL_LIST_SPACES` uses `limit` and `skip` parameters. When you have many spaces, iterate by incrementing `skip` until no more results are returned to avoid missing spaces.\n- **Scope limitations:** These tools only manage space-level metadata (names). They cannot create or modify entries, content types, or assets within a space.\n- **Auth/permissions mismatch:** Updates via `CONTENTFUL_UPDATE_SPACE` will fail if your token lacks space management scopes, even if reads via `CONTENTFUL_GET_SPACE` succeed. Verify your token has write permissions.\n- **Space ID format:** The `space_id` must match the pattern `^[a-zA-Z0-9-_.]{1,64}$`. Invalid characters will be rejected.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `CONTENTFUL_LIST_SPACES` | List all spaces accessible to your account |\n| `CONTENTFUL_GET_SPACE` | Retrieve detailed metadata for a single space |\n| `CONTENTFUL_UPDATE_SPACE` | Update the name of a space (requires version) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/contentful-graphql-automation/SKILL.md",
    "content": "---\nname: contentful-graphql-automation\ndescription: \"Automate Contentful Graphql tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Contentful Graphql Automation via Rube MCP\n\nAutomate Contentful Graphql operations through Composio's Contentful Graphql toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/contentful_graphql](https://composio.dev/toolkits/contentful_graphql)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Contentful Graphql connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `contentful_graphql`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `contentful_graphql`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Contentful Graphql operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Contentful Graphql task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"contentful_graphql\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Contentful Graphql-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `contentful_graphql` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/control-d-automation/SKILL.md",
    "content": "---\nname: control-d-automation\ndescription: \"Automate Control D tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Control D Automation via Rube MCP\n\nAutomate Control D operations through Composio's Control D toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/control_d](https://composio.dev/toolkits/control_d)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Control D connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `control_d`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `control_d`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Control D operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Control D task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"control_d\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Control D-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `control_d` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/conversion-tools-automation/SKILL.md",
    "content": "---\nname: conversion-tools-automation\ndescription: \"Automate Conversion Tools tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Conversion Tools Automation via Rube MCP\n\nAutomate Conversion Tools operations through Composio's Conversion Tools toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/conversion_tools](https://composio.dev/toolkits/conversion_tools)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Conversion Tools connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `conversion_tools`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `conversion_tools`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Conversion Tools operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Conversion Tools task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"conversion_tools\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Conversion Tools-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `conversion_tools` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/convertapi-automation/SKILL.md",
    "content": "---\nname: convertapi-automation\ndescription: \"Automate Convertapi tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Convertapi Automation via Rube MCP\n\nAutomate Convertapi operations through Composio's Convertapi toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/convertapi](https://composio.dev/toolkits/convertapi)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Convertapi connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `convertapi`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `convertapi`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Convertapi operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Convertapi task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"convertapi\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Convertapi-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `convertapi` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/conveyor-automation/SKILL.md",
    "content": "---\nname: conveyor-automation\ndescription: \"Automate Conveyor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Conveyor Automation via Rube MCP\n\nAutomate Conveyor operations through Composio's Conveyor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/conveyor](https://composio.dev/toolkits/conveyor)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Conveyor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `conveyor`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `conveyor`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Conveyor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Conveyor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"conveyor\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Conveyor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `conveyor` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/convolo-ai-automation/SKILL.md",
    "content": "---\nname: convolo-ai-automation\ndescription: \"Automate Convolo AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Convolo AI Automation via Rube MCP\n\nAutomate Convolo AI operations through Composio's Convolo AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/convolo_ai](https://composio.dev/toolkits/convolo_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Convolo AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `convolo_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `convolo_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Convolo AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Convolo AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"convolo_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Convolo AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `convolo_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/corrently-automation/SKILL.md",
    "content": "---\nname: corrently-automation\ndescription: \"Automate Corrently tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Corrently Automation via Rube MCP\n\nAutomate Corrently operations through Composio's Corrently toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/corrently](https://composio.dev/toolkits/corrently)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Corrently connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `corrently`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `corrently`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Corrently operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Corrently task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"corrently\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Corrently-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `corrently` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/countdown-api-automation/SKILL.md",
    "content": "---\nname: countdown-api-automation\ndescription: \"Automate Countdown API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Countdown API Automation via Rube MCP\n\nAutomate Countdown API operations through Composio's Countdown API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/countdown_api](https://composio.dev/toolkits/countdown_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Countdown API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `countdown_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `countdown_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Countdown API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Countdown API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"countdown_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Countdown API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `countdown_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/coupa-automation/SKILL.md",
    "content": "---\nname: coupa-automation\ndescription: \"Automate Coupa tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Coupa Automation via Rube MCP\n\nAutomate Coupa operations through Composio's Coupa toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/coupa](https://composio.dev/toolkits/coupa)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Coupa connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `coupa`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `coupa`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Coupa operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Coupa task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"coupa\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Coupa-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `coupa` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/craftmypdf-automation/SKILL.md",
    "content": "---\nname: craftmypdf-automation\ndescription: \"Automate Craftmypdf tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Craftmypdf Automation via Rube MCP\n\nAutomate Craftmypdf operations through Composio's Craftmypdf toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/craftmypdf](https://composio.dev/toolkits/craftmypdf)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Craftmypdf connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `craftmypdf`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `craftmypdf`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Craftmypdf operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Craftmypdf task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"craftmypdf\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Craftmypdf-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `craftmypdf` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/crowdin-automation/SKILL.md",
    "content": "---\nname: crowdin-automation\ndescription: \"Automate Crowdin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Crowdin Automation via Rube MCP\n\nAutomate Crowdin operations through Composio's Crowdin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/crowdin](https://composio.dev/toolkits/crowdin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Crowdin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `crowdin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `crowdin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Crowdin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Crowdin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"crowdin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Crowdin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `crowdin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/crustdata-automation/SKILL.md",
    "content": "---\nname: crustdata-automation\ndescription: \"Automate Crustdata tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Crustdata Automation via Rube MCP\n\nAutomate Crustdata operations through Composio's Crustdata toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/crustdata](https://composio.dev/toolkits/crustdata)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Crustdata connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `crustdata`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `crustdata`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Crustdata operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Crustdata task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"crustdata\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Crustdata-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `crustdata` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cults-automation/SKILL.md",
    "content": "---\nname: cults-automation\ndescription: \"Automate Cults tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cults Automation via Rube MCP\n\nAutomate Cults operations through Composio's Cults toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cults](https://composio.dev/toolkits/cults)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cults connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cults`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cults`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cults operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cults task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cults\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cults-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cults` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/curated-automation/SKILL.md",
    "content": "---\nname: curated-automation\ndescription: \"Automate Curated tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Curated Automation via Rube MCP\n\nAutomate Curated operations through Composio's Curated toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/curated](https://composio.dev/toolkits/curated)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Curated connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `curated`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `curated`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Curated operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Curated task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"curated\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Curated-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `curated` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/currents-api-automation/SKILL.md",
    "content": "---\nname: currents-api-automation\ndescription: \"Automate Currents API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Currents API Automation via Rube MCP\n\nAutomate Currents API operations through Composio's Currents API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/currents_api](https://composio.dev/toolkits/currents_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Currents API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `currents_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `currents_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Currents API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Currents API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"currents_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Currents API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `currents_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/customerio-automation/SKILL.md",
    "content": "---\nname: Customer.io Automation\ndescription: \"Automate customer engagement workflows including broadcast triggers, message analytics, segment management, and newsletter tracking through Customer.io via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Customer.io Automation\n\nAutomate customer engagement operations -- trigger targeted broadcasts, retrieve delivery metrics, manage audience segments, list newsletters and transactional templates, and inspect trigger execution history -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/customerio](https://composio.dev/toolkits/customerio)\n\n---\n\n## Setup\n\n1. Connect your Customer.io account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `CUSTOMERIO_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. Trigger a Broadcast\nManually fire a pre-configured broadcast to a specific audience with personalization data.\n\n**Tool:** `CUSTOMERIO_TRIGGER_BROADCAST`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `broadcast_id` | integer | Yes | Broadcast ID from Customer.io Triggering Details |\n| `ids` | array | No | List of customer IDs to target |\n| `emails` | array | No | List of email addresses to target |\n| `recipients` | object | No | Complex filter with `and`/`or`/`not`/`segment` operators |\n| `per_user_data` | array | No | Per-user personalization with `id`/`email` + `data` |\n| `data` | object | No | Global key-value data for Liquid template personalization |\n| `data_file_url` | string | No | URL to JSON file with per-line user data |\n| `email_add_duplicates` | boolean | No | Allow duplicate recipients (default: false) |\n| `email_ignore_missing` | boolean | No | Skip people without emails (default: false) |\n| `id_ignore_missing` | boolean | No | Skip people without customer IDs (default: false) |\n\n**Important:** Provide exactly ONE audience option: `recipients`, `ids`, `emails`, `per_user_data`, or `data_file_url`. Rate limit: 1 request per 10 seconds per broadcast.\n\n---\n\n### 2. Retrieve Message Delivery Metrics\nFetch paginated delivery metrics for messages with filtering by campaign, type, and time window.\n\n**Tool:** `CUSTOMERIO_GET_MESSAGES`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `type` | string | No | Message type: `email`, `webhook`, `twilio`, `slack`, `push`, `in_app` |\n| `metric` | string | No | Metric: `attempted`, `sent`, `delivered`, `opened`, `clicked`, `converted` |\n| `campaign_id` | integer | No | Filter by campaign ID |\n| `newsletter_id` | integer | No | Filter by newsletter ID |\n| `action_id` | integer | No | Filter by action ID |\n| `start_ts` | integer | No | Start of time window (Unix timestamp) |\n| `end_ts` | integer | No | End of time window (Unix timestamp) |\n| `limit` | integer | No | Results per page, 1-1000 (default: 50) |\n| `start` | string | No | Pagination token from previous response `next` value |\n| `drafts` | boolean | No | Return draft messages instead of active/sent |\n\n---\n\n### 3. List Audience Segments\nRetrieve all segments defined in your workspace for audience analysis and broadcast targeting.\n\n**Tool:** `CUSTOMERIO_GET_SEGMENTS`\n\n```\nNo parameters required -- returns all segments with IDs and metadata.\n```\n\nUse segment IDs when targeting broadcasts via the `recipients.segment.id` filter.\n\n---\n\n### 4. List Newsletters\nPaginate through all newsletter metadata for tracking and analysis.\n\n**Tool:** `CUSTOMERIO_LIST_NEWSLETTERS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `limit` | integer | No | Max per page, 1-100 |\n| `sort` | string | No | `asc` (chronological) or `desc` (reverse) |\n| `start` | string | No | Pagination cursor from previous response `next` value |\n\n---\n\n### 5. Discover Transactional Message Templates\nList all transactional message templates to find IDs for sending via the API.\n\n**Tool:** `CUSTOMERIO_LIST_TRANSACTIONAL_MESSAGES`\n\n```\nNo parameters required -- returns template IDs and trigger names.\n```\n\n---\n\n### 6. Inspect Broadcast Trigger History\nReview all trigger executions for a broadcast and inspect individual trigger details.\n\n**Tools:** `CUSTOMERIO_GET_TRIGGERS` and `CUSTOMERIO_GET_TRIGGER`\n\n**List all triggers for a broadcast:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `broadcast_id` | integer | Yes | The broadcast/campaign ID |\n\n**Get a specific trigger:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `broadcast_id` | integer | Yes | The campaign/broadcast ID |\n| `trigger_id` | string | Yes | Trigger identifier (e.g., `456` or `5-37`) |\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Mutually exclusive audience params** | `CUSTOMERIO_TRIGGER_BROADCAST` requires exactly ONE of `recipients`, `ids`, `emails`, `per_user_data`, or `data_file_url` -- providing multiple causes errors |\n| **Rate limiting on broadcasts** | Broadcasts are limited to 1 trigger request per 10 seconds per broadcast ID |\n| **Unix timestamp format** | `start_ts` and `end_ts` in `CUSTOMERIO_GET_MESSAGES` must be Unix timestamps, not ISO strings |\n| **Pagination tokens** | Messages and newsletters use cursor-based pagination via the `start` parameter -- use the `next` value from previous responses |\n| **Segment ID resolution** | To target a segment in a broadcast, first fetch segment IDs via `CUSTOMERIO_GET_SEGMENTS`, then reference by ID in `recipients.segment.id` |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `CUSTOMERIO_TRIGGER_BROADCAST` | Trigger a broadcast to a defined audience |\n| `CUSTOMERIO_GET_MESSAGES` | Retrieve message delivery metrics with filters |\n| `CUSTOMERIO_GET_SEGMENTS` | List all audience segments |\n| `CUSTOMERIO_GET_SEGMENT_DETAILS` | Get details for a specific segment |\n| `CUSTOMERIO_LIST_NEWSLETTERS` | Paginate through newsletters |\n| `CUSTOMERIO_LIST_TRANSACTIONAL_MESSAGES` | List transactional message templates |\n| `CUSTOMERIO_GET_TRIGGERS` | List all trigger executions for a broadcast |\n| `CUSTOMERIO_GET_TRIGGER` | Inspect a specific trigger execution |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/customgpt-automation/SKILL.md",
    "content": "---\nname: customgpt-automation\ndescription: \"Automate Customgpt tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Customgpt Automation via Rube MCP\n\nAutomate Customgpt operations through Composio's Customgpt toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/customgpt](https://composio.dev/toolkits/customgpt)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Customgpt connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `customgpt`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `customgpt`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Customgpt operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Customgpt task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"customgpt\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Customgpt-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `customgpt` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/customjs-automation/SKILL.md",
    "content": "---\nname: customjs-automation\ndescription: \"Automate Customjs tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Customjs Automation via Rube MCP\n\nAutomate Customjs operations through Composio's Customjs toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/customjs](https://composio.dev/toolkits/customjs)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Customjs connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `customjs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `customjs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Customjs operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Customjs task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"customjs\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Customjs-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `customjs` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/cutt-ly-automation/SKILL.md",
    "content": "---\nname: cutt-ly-automation\ndescription: \"Automate Cutt Ly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Cutt Ly Automation via Rube MCP\n\nAutomate Cutt Ly operations through Composio's Cutt Ly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/cutt_ly](https://composio.dev/toolkits/cutt_ly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Cutt Ly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `cutt_ly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `cutt_ly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Cutt Ly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Cutt Ly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"cutt_ly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Cutt Ly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `cutt_ly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/d2lbrightspace-automation/SKILL.md",
    "content": "---\nname: d2lbrightspace-automation\ndescription: \"Automate D2lbrightspace tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# D2lbrightspace Automation via Rube MCP\n\nAutomate D2lbrightspace operations through Composio's D2lbrightspace toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/d2lbrightspace](https://composio.dev/toolkits/d2lbrightspace)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active D2lbrightspace connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `d2lbrightspace`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `d2lbrightspace`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"D2lbrightspace operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific D2lbrightspace task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"d2lbrightspace\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with D2lbrightspace-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `d2lbrightspace` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dadata-ru-automation/SKILL.md",
    "content": "---\nname: dadata-ru-automation\ndescription: \"Automate Dadata Ru tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dadata Ru Automation via Rube MCP\n\nAutomate Dadata Ru operations through Composio's Dadata Ru toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dadata_ru](https://composio.dev/toolkits/dadata_ru)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dadata Ru connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dadata_ru`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dadata_ru`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dadata Ru operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dadata Ru task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dadata_ru\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dadata Ru-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dadata_ru` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/daffy-automation/SKILL.md",
    "content": "---\nname: daffy-automation\ndescription: \"Automate Daffy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Daffy Automation via Rube MCP\n\nAutomate Daffy operations through Composio's Daffy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/daffy](https://composio.dev/toolkits/daffy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Daffy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `daffy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `daffy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Daffy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Daffy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"daffy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Daffy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `daffy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dailybot-automation/SKILL.md",
    "content": "---\nname: dailybot-automation\ndescription: \"Automate Dailybot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dailybot Automation via Rube MCP\n\nAutomate Dailybot operations through Composio's Dailybot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dailybot](https://composio.dev/toolkits/dailybot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dailybot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dailybot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dailybot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dailybot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dailybot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dailybot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dailybot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dailybot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/datagma-automation/SKILL.md",
    "content": "---\nname: datagma-automation\ndescription: \"Automate Datagma tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Datagma Automation via Rube MCP\n\nAutomate Datagma operations through Composio's Datagma toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/datagma](https://composio.dev/toolkits/datagma)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Datagma connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `datagma`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `datagma`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Datagma operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Datagma task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"datagma\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Datagma-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `datagma` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/datarobot-automation/SKILL.md",
    "content": "---\nname: datarobot-automation\ndescription: \"Automate Datarobot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Datarobot Automation via Rube MCP\n\nAutomate Datarobot operations through Composio's Datarobot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/datarobot](https://composio.dev/toolkits/datarobot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Datarobot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `datarobot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `datarobot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Datarobot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Datarobot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"datarobot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Datarobot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `datarobot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/deadline-funnel-automation/SKILL.md",
    "content": "---\nname: deadline-funnel-automation\ndescription: \"Automate Deadline Funnel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Deadline Funnel Automation via Rube MCP\n\nAutomate Deadline Funnel operations through Composio's Deadline Funnel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/deadline_funnel](https://composio.dev/toolkits/deadline_funnel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Deadline Funnel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `deadline_funnel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `deadline_funnel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Deadline Funnel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Deadline Funnel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"deadline_funnel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Deadline Funnel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `deadline_funnel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/deel-automation/SKILL.md",
    "content": "---\nname: deel-automation\ndescription: \"Automate Deel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Deel Automation via Rube MCP\n\nAutomate Deel operations through Composio's Deel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/deel](https://composio.dev/toolkits/deel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Deel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `deel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `deel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Deel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Deel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"deel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Deel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `deel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/deepgram-automation/SKILL.md",
    "content": "---\nname: deepgram-automation\ndescription: \"Automate Deepgram tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Deepgram Automation via Rube MCP\n\nAutomate Deepgram operations through Composio's Deepgram toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/deepgram](https://composio.dev/toolkits/deepgram)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Deepgram connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `deepgram`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `deepgram`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Deepgram operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Deepgram task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"deepgram\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Deepgram-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `deepgram` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/demio-automation/SKILL.md",
    "content": "---\nname: demio-automation\ndescription: \"Automate Demio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Demio Automation via Rube MCP\n\nAutomate Demio operations through Composio's Demio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/demio](https://composio.dev/toolkits/demio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Demio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `demio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `demio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Demio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Demio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"demio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Demio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `demio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/desktime-automation/SKILL.md",
    "content": "---\nname: desktime-automation\ndescription: \"Automate Desktime tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Desktime Automation via Rube MCP\n\nAutomate Desktime operations through Composio's Desktime toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/desktime](https://composio.dev/toolkits/desktime)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Desktime connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `desktime`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `desktime`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Desktime operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Desktime task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"desktime\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Desktime-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `desktime` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/detrack-automation/SKILL.md",
    "content": "---\nname: detrack-automation\ndescription: \"Automate Detrack tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Detrack Automation via Rube MCP\n\nAutomate Detrack operations through Composio's Detrack toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/detrack](https://composio.dev/toolkits/detrack)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Detrack connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `detrack`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `detrack`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Detrack operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Detrack task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"detrack\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Detrack-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `detrack` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dialmycalls-automation/SKILL.md",
    "content": "---\nname: dialmycalls-automation\ndescription: \"Automate Dialmycalls tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dialmycalls Automation via Rube MCP\n\nAutomate Dialmycalls operations through Composio's Dialmycalls toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dialmycalls](https://composio.dev/toolkits/dialmycalls)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dialmycalls connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dialmycalls`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dialmycalls`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dialmycalls operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dialmycalls task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dialmycalls\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dialmycalls-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dialmycalls` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dialpad-automation/SKILL.md",
    "content": "---\nname: dialpad-automation\ndescription: \"Automate Dialpad tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dialpad Automation via Rube MCP\n\nAutomate Dialpad operations through Composio's Dialpad toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dialpad](https://composio.dev/toolkits/dialpad)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dialpad connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dialpad`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dialpad`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dialpad operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dialpad task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dialpad\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dialpad-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dialpad` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dictionary-api-automation/SKILL.md",
    "content": "---\nname: dictionary-api-automation\ndescription: \"Automate Dictionary API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dictionary API Automation via Rube MCP\n\nAutomate Dictionary API operations through Composio's Dictionary API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dictionary_api](https://composio.dev/toolkits/dictionary_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dictionary API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dictionary_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dictionary_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dictionary API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dictionary API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dictionary_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dictionary API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dictionary_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/diffbot-automation/SKILL.md",
    "content": "---\nname: diffbot-automation\ndescription: \"Automate Diffbot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Diffbot Automation via Rube MCP\n\nAutomate Diffbot operations through Composio's Diffbot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/diffbot](https://composio.dev/toolkits/diffbot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Diffbot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `diffbot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `diffbot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Diffbot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Diffbot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"diffbot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Diffbot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `diffbot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/digicert-automation/SKILL.md",
    "content": "---\nname: digicert-automation\ndescription: \"Automate Digicert tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Digicert Automation via Rube MCP\n\nAutomate Digicert operations through Composio's Digicert toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/digicert](https://composio.dev/toolkits/digicert)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Digicert connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `digicert`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `digicert`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Digicert operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Digicert task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"digicert\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Digicert-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `digicert` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/digital-ocean-automation/SKILL.md",
    "content": "---\nname: digital-ocean-automation\ndescription: \"Automate DigitalOcean tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# DigitalOcean Automation via Rube MCP\n\nAutomate DigitalOcean operations through Composio's DigitalOcean toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/digital_ocean](https://composio.dev/toolkits/digital_ocean)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active DigitalOcean connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `digital_ocean`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `digital_ocean`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"DigitalOcean operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific DigitalOcean task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"digital_ocean\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with DigitalOcean-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `digital_ocean` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/discordbot-automation/SKILL.md",
    "content": "---\nname: discordbot-automation\ndescription: \"Automate Discordbot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Discordbot Automation via Rube MCP\n\nAutomate Discordbot operations through Composio's Discordbot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/discordbot](https://composio.dev/toolkits/discordbot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Discordbot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `discordbot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `discordbot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Discordbot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Discordbot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"discordbot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Discordbot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `discordbot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dnsfilter-automation/SKILL.md",
    "content": "---\nname: dnsfilter-automation\ndescription: \"Automate Dnsfilter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dnsfilter Automation via Rube MCP\n\nAutomate Dnsfilter operations through Composio's Dnsfilter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dnsfilter](https://composio.dev/toolkits/dnsfilter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dnsfilter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dnsfilter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dnsfilter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dnsfilter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dnsfilter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dnsfilter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dnsfilter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dnsfilter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dock-certs-automation/SKILL.md",
    "content": "---\nname: dock-certs-automation\ndescription: \"Automate Dock Certs tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dock Certs Automation via Rube MCP\n\nAutomate Dock Certs operations through Composio's Dock Certs toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dock_certs](https://composio.dev/toolkits/dock_certs)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dock Certs connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dock_certs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dock_certs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dock Certs operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dock Certs task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dock_certs\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dock Certs-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dock_certs` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docker-hub-automation/SKILL.md",
    "content": "---\nname: Docker Hub Automation\ndescription: \"Automate Docker Hub operations -- manage organizations, repositories, teams, members, and webhooks via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Docker Hub Automation\n\nAutomate your Docker Hub workflows -- create and manage organizations, repositories, teams, add members, set up image push webhooks, and list container images.\n\n**Toolkit docs:** [composio.dev/toolkits/docker_hub](https://composio.dev/toolkits/docker_hub)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Docker Hub account when prompted (JWT/token authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List Organizations\n\nUse `DOCKER_HUB_LIST_ORGANIZATIONS` to discover which organizations the authenticated user belongs to.\n\n```\nTool: DOCKER_HUB_LIST_ORGANIZATIONS\nInputs:\n  - page: integer (1-indexed, default 1)\n  - page_size: integer (1-100, default 25)\n```\n\n### 2. Create an Organization\n\nUse `DOCKER_HUB_CREATE_ORGANIZATION` to programmatically create a new Docker Hub organization.\n\n```\nTool: DOCKER_HUB_CREATE_ORGANIZATION\nInputs:\n  - orgname: string (required) -- lowercase, letters/numbers/._- only, min 2 chars\n  - company: string (optional) -- company name associated with the org\n```\n\n**Note:** Requires JWT authentication obtained via `/v2/users/login` and may have restricted access.\n\n### 3. Get Organization Details and Repositories\n\nUse `DOCKER_HUB_GET_ORGANIZATION` to retrieve namespace info and its repositories. Works with any public namespace.\n\n```\nTool: DOCKER_HUB_GET_ORGANIZATION\nInputs:\n  - organization: string (required) -- e.g., \"docker\", \"bitnami\", \"library\"\n```\n\n### 4. Create a Repository\n\nUse `DOCKER_HUB_CREATE_REPOSITORY` to create public or private repositories under a namespace.\n\n```\nTool: DOCKER_HUB_CREATE_REPOSITORY\nInputs:\n  - namespace: string (required) -- Docker Hub username or org name\n  - name: string (required) -- lowercase; letters, numbers, ._- allowed\n  - description: string (optional) -- max 100 characters\n  - full_description: string (optional) -- Markdown README content\n  - is_private: boolean (default false) -- private repos require paid plan\n```\n\n### 5. List Repositories with Filtering\n\nUse `DOCKER_HUB_LIST_REPOSITORIES` to enumerate repos within a namespace with sorting and content-type filtering.\n\n```\nTool: DOCKER_HUB_LIST_REPOSITORIES\nInputs:\n  - namespace: string (required) -- e.g., \"library\", \"myorg\"\n  - ordering: \"name\" | \"last_updated\" | \"pull_count\" (prefix with - for descending)\n  - page: integer (default 1)\n  - page_size: integer (1-100, default 25)\n  - content_types: string (comma-separated, e.g., \"image,artifact\")\n```\n\n### 6. Manage Teams, Members, and Webhooks\n\nUse `DOCKER_HUB_LIST_TEAMS` to list teams within an org, `DOCKER_HUB_ADD_ORG_MEMBER` to invite users, and `DOCKER_HUB_CREATE_WEBHOOK` for push notifications.\n\n```\nTool: DOCKER_HUB_LIST_TEAMS\n  - Lists all teams/groups within a Docker Hub organization\n\nTool: DOCKER_HUB_ADD_ORG_MEMBER\n  - Invite a user to join an organization by Docker ID or email\n  - Requires owner or admin permissions\n\nTool: DOCKER_HUB_CREATE_WEBHOOK\n  - Create a webhook on a repository for image push notifications\n  - Two-step process: create webhook, then add hook URL\n  - Requires admin permissions on the repository\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| JWT authentication | `DOCKER_HUB_CREATE_ORGANIZATION` requires JWT auth from `/v2/users/login` -- standard API tokens may not suffice. |\n| Private repo limits | Creating private repos (`is_private: true`) requires a paid Docker Hub plan. |\n| Org name constraints | Organization names must be lowercase, at least 2 characters, containing only letters, numbers, `.`, `_`, or `-`. |\n| Webhook two-step | `DOCKER_HUB_CREATE_WEBHOOK` is a two-step process: first create the webhook with a name, then add a hook URL to it. |\n| Pagination | All list endpoints use page-based pagination -- iterate pages until results are exhausted. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `DOCKER_HUB_LIST_ORGANIZATIONS` | List orgs the user belongs to |\n| `DOCKER_HUB_CREATE_ORGANIZATION` | Create a new Docker Hub organization |\n| `DOCKER_HUB_GET_ORGANIZATION` | Get org details and repository list |\n| `DOCKER_HUB_CREATE_REPOSITORY` | Create a repository under a namespace |\n| `DOCKER_HUB_LIST_REPOSITORIES` | List repos with filtering and sorting |\n| `DOCKER_HUB_LIST_TEAMS` | List teams/groups within an org |\n| `DOCKER_HUB_ADD_ORG_MEMBER` | Invite a user to an organization |\n| `DOCKER_HUB_CREATE_WEBHOOK` | Create push-notification webhook on a repo |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docker_hub-automation/SKILL.md",
    "content": "---\nname: docker_hub-automation\ndescription: \"Automate Docker Hub tasks via Rube MCP (Composio): repositories, images, tags, and container registry management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docker Hub Automation via Rube MCP\n\nAutomate Docker Hub operations through Composio's Docker Hub toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docker_hub](https://composio.dev/toolkits/docker_hub)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docker Hub connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docker_hub`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docker_hub`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"repositories, images, tags, and container registry management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Docker Hub\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Docker Hub Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Docker Hub tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Docker Hub Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Docker Hub operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Docker Hub connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docker Hub-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docker_hub` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/docker_hub](https://composio.dev/toolkits/docker_hub)\n"
  },
  {
    "path": "composio-skills/docmosis-automation/SKILL.md",
    "content": "---\nname: docmosis-automation\ndescription: \"Automate Docmosis tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docmosis Automation via Rube MCP\n\nAutomate Docmosis operations through Composio's Docmosis toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docmosis](https://composio.dev/toolkits/docmosis)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docmosis connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docmosis`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docmosis`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docmosis operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docmosis task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docmosis\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docmosis-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docmosis` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docnify-automation/SKILL.md",
    "content": "---\nname: docnify-automation\ndescription: \"Automate Docnify tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docnify Automation via Rube MCP\n\nAutomate Docnify operations through Composio's Docnify toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docnify](https://composio.dev/toolkits/docnify)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docnify connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docnify`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docnify`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docnify operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docnify task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docnify\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docnify-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docnify` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docsbot-ai-automation/SKILL.md",
    "content": "---\nname: docsbot-ai-automation\ndescription: \"Automate Docsbot AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docsbot AI Automation via Rube MCP\n\nAutomate Docsbot AI operations through Composio's Docsbot AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docsbot_ai](https://composio.dev/toolkits/docsbot_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docsbot AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docsbot_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docsbot_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docsbot AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docsbot AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docsbot_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docsbot AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docsbot_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docsumo-automation/SKILL.md",
    "content": "---\nname: docsumo-automation\ndescription: \"Automate Docsumo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docsumo Automation via Rube MCP\n\nAutomate Docsumo operations through Composio's Docsumo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docsumo](https://composio.dev/toolkits/docsumo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docsumo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docsumo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docsumo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docsumo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docsumo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docsumo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docsumo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docsumo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docugenerate-automation/SKILL.md",
    "content": "---\nname: docugenerate-automation\ndescription: \"Automate Docugenerate tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docugenerate Automation via Rube MCP\n\nAutomate Docugenerate operations through Composio's Docugenerate toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docugenerate](https://composio.dev/toolkits/docugenerate)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docugenerate connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docugenerate`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docugenerate`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docugenerate operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docugenerate task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docugenerate\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docugenerate-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docugenerate` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/documenso-automation/SKILL.md",
    "content": "---\nname: documenso-automation\ndescription: \"Automate Documenso tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Documenso Automation via Rube MCP\n\nAutomate Documenso operations through Composio's Documenso toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/documenso](https://composio.dev/toolkits/documenso)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Documenso connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `documenso`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `documenso`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Documenso operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Documenso task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"documenso\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Documenso-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `documenso` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/documint-automation/SKILL.md",
    "content": "---\nname: documint-automation\ndescription: \"Automate Documint tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Documint Automation via Rube MCP\n\nAutomate Documint operations through Composio's Documint toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/documint](https://composio.dev/toolkits/documint)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Documint connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `documint`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `documint`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Documint operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Documint task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"documint\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Documint-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `documint` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docupilot-automation/SKILL.md",
    "content": "---\nname: docupilot-automation\ndescription: \"Automate Docupilot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docupilot Automation via Rube MCP\n\nAutomate Docupilot operations through Composio's Docupilot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docupilot](https://composio.dev/toolkits/docupilot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docupilot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docupilot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docupilot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docupilot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docupilot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docupilot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docupilot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docupilot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docupost-automation/SKILL.md",
    "content": "---\nname: docupost-automation\ndescription: \"Automate Docupost tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docupost Automation via Rube MCP\n\nAutomate Docupost operations through Composio's Docupost toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docupost](https://composio.dev/toolkits/docupost)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docupost connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docupost`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docupost`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docupost operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docupost task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docupost\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docupost-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docupost` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/docuseal-automation/SKILL.md",
    "content": "---\nname: docuseal-automation\ndescription: \"Automate Docuseal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Docuseal Automation via Rube MCP\n\nAutomate Docuseal operations through Composio's Docuseal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/docuseal](https://composio.dev/toolkits/docuseal)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Docuseal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `docuseal`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `docuseal`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Docuseal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Docuseal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"docuseal\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Docuseal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `docuseal` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/doppler-marketing-automation-automation/SKILL.md",
    "content": "---\nname: doppler-marketing-automation-automation\ndescription: \"Automate Doppler Marketing Automation tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Doppler Marketing Automation Automation via Rube MCP\n\nAutomate Doppler Marketing Automation operations through Composio's Doppler Marketing Automation toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/doppler_marketing_automation](https://composio.dev/toolkits/doppler_marketing_automation)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Doppler Marketing Automation connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_marketing_automation`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_marketing_automation`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Doppler Marketing Automation operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Doppler Marketing Automation task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"doppler_marketing_automation\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Doppler Marketing Automation-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_marketing_automation` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/doppler-secretops-automation/SKILL.md",
    "content": "---\nname: doppler-secretops-automation\ndescription: \"Automate Doppler Secretops tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Doppler Secretops Automation via Rube MCP\n\nAutomate Doppler Secretops operations through Composio's Doppler Secretops toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/doppler_secretops](https://composio.dev/toolkits/doppler_secretops)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Doppler Secretops connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_secretops`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_secretops`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Doppler Secretops operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Doppler Secretops task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"doppler_secretops\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Doppler Secretops-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `doppler_secretops` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dotsimple-automation/SKILL.md",
    "content": "---\nname: dotsimple-automation\ndescription: \"Automate Dotsimple tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dotsimple Automation via Rube MCP\n\nAutomate Dotsimple operations through Composio's Dotsimple toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dotsimple](https://composio.dev/toolkits/dotsimple)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dotsimple connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dotsimple`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dotsimple`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dotsimple operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dotsimple task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dotsimple\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dotsimple-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dotsimple` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dovetail-automation/SKILL.md",
    "content": "---\nname: dovetail-automation\ndescription: \"Automate Dovetail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dovetail Automation via Rube MCP\n\nAutomate Dovetail operations through Composio's Dovetail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dovetail](https://composio.dev/toolkits/dovetail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dovetail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dovetail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dovetail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dovetail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dovetail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dovetail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dovetail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dovetail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dpd2-automation/SKILL.md",
    "content": "---\nname: dpd2-automation\ndescription: \"Automate Dpd2 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dpd2 Automation via Rube MCP\n\nAutomate Dpd2 operations through Composio's Dpd2 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dpd2](https://composio.dev/toolkits/dpd2)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dpd2 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dpd2`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dpd2`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dpd2 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dpd2 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dpd2\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dpd2-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dpd2` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/draftable-automation/SKILL.md",
    "content": "---\nname: draftable-automation\ndescription: \"Automate Draftable tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Draftable Automation via Rube MCP\n\nAutomate Draftable operations through Composio's Draftable toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/draftable](https://composio.dev/toolkits/draftable)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Draftable connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `draftable`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `draftable`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Draftable operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Draftable task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"draftable\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Draftable-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `draftable` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dreamstudio-automation/SKILL.md",
    "content": "---\nname: dreamstudio-automation\ndescription: \"Automate Dreamstudio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dreamstudio Automation via Rube MCP\n\nAutomate Dreamstudio operations through Composio's Dreamstudio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dreamstudio](https://composio.dev/toolkits/dreamstudio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dreamstudio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dreamstudio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dreamstudio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dreamstudio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dreamstudio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dreamstudio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dreamstudio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dreamstudio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/drip-jobs-automation/SKILL.md",
    "content": "---\nname: drip-jobs-automation\ndescription: \"Automate Drip Jobs tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Drip Jobs Automation via Rube MCP\n\nAutomate Drip Jobs operations through Composio's Drip Jobs toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/drip_jobs](https://composio.dev/toolkits/drip_jobs)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Drip Jobs connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `drip_jobs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `drip_jobs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Drip Jobs operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Drip Jobs task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"drip_jobs\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Drip Jobs-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `drip_jobs` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dripcel-automation/SKILL.md",
    "content": "---\nname: dripcel-automation\ndescription: \"Automate Dripcel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dripcel Automation via Rube MCP\n\nAutomate Dripcel operations through Composio's Dripcel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dripcel](https://composio.dev/toolkits/dripcel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dripcel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dripcel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dripcel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dripcel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dripcel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dripcel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dripcel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dripcel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dromo-automation/SKILL.md",
    "content": "---\nname: dromo-automation\ndescription: \"Automate Dromo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dromo Automation via Rube MCP\n\nAutomate Dromo operations through Composio's Dromo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dromo](https://composio.dev/toolkits/dromo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dromo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dromo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dromo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dromo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dromo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dromo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dromo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dromo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dropbox-sign-automation/SKILL.md",
    "content": "---\nname: dropbox-sign-automation\ndescription: \"Automate Dropbox Sign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dropbox Sign Automation via Rube MCP\n\nAutomate Dropbox Sign operations through Composio's Dropbox Sign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dropbox_sign](https://composio.dev/toolkits/dropbox_sign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dropbox Sign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dropbox_sign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dropbox_sign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dropbox Sign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dropbox Sign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dropbox_sign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dropbox Sign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dropbox_sign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dropcontact-automation/SKILL.md",
    "content": "---\nname: dropcontact-automation\ndescription: \"Automate Dropcontact tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dropcontact Automation via Rube MCP\n\nAutomate Dropcontact operations through Composio's Dropcontact toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dropcontact](https://composio.dev/toolkits/dropcontact)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dropcontact connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dropcontact`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dropcontact`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dropcontact operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dropcontact task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dropcontact\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dropcontact-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dropcontact` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dungeon-fighter-online-automation/SKILL.md",
    "content": "---\nname: dungeon-fighter-online-automation\ndescription: \"Automate Dungeon Fighter Online tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Dungeon Fighter Online Automation via Rube MCP\n\nAutomate Dungeon Fighter Online operations through Composio's Dungeon Fighter Online toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/dungeon_fighter_online](https://composio.dev/toolkits/dungeon_fighter_online)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Dungeon Fighter Online connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `dungeon_fighter_online`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `dungeon_fighter_online`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Dungeon Fighter Online operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Dungeon Fighter Online task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"dungeon_fighter_online\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Dungeon Fighter Online-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `dungeon_fighter_online` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/dynamics365-automation/SKILL.md",
    "content": "---\nname: Dynamics 365 Automation\ndescription: \"Dynamics 365 Automation: manage CRM contacts, accounts, leads, opportunities, sales orders, invoices, and cases via the Dynamics CRM Web API\"\nrequires:\n  mcp: [rube]\n---\n\n# Dynamics 365 Automation\n\nAutomate Microsoft Dynamics 365 CRM operations including creating and updating contacts, accounts, leads, opportunities, sales orders, invoices, and support cases.\n\n**Toolkit docs:** [composio.dev/toolkits/dynamics365](https://composio.dev/toolkits/dynamics365)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `dynamics365` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. Manage Leads\n\nCreate, update, retrieve, and list lead records.\n\n**Tools:**\n- `DYNAMICS365_DYNAMICSCRM_CREATE_LEAD` -- Create a new lead\n- `DYNAMICS365_DYNAMICSCRM_UPDATE_LEAD` -- Update an existing lead\n- `DYNAMICS365_DYNAMICSCRM_GET_A_LEAD` -- Retrieve a lead by GUID\n- `DYNAMICS365_DYNAMICSCRM_GET_ALL_LEADS` -- List/filter all leads\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_CREATE_LEAD`:**\n- `firstname` -- First name of the lead\n- `lastname` -- Last name of the lead\n- `emailaddress1` -- Primary email address\n- `telephone1` -- Primary phone number\n- `companyname` -- Associated company name\n- `subject` -- Brief title/description\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_GET_ALL_LEADS`:**\n- `filter` -- OData filter, e.g., `\"contains(fullname,'John')\"`\n- `select` -- Fields to return, e.g., `\"fullname,emailaddress1\"`\n- `orderby` -- Sort expression, e.g., `\"createdon desc\"`\n- `top` -- Max number of results\n\n**Example:**\n```\nTool: DYNAMICS365_DYNAMICSCRM_CREATE_LEAD\nArguments:\n  firstname: \"Jane\"\n  lastname: \"Smith\"\n  emailaddress1: \"jane.smith@example.com\"\n  companyname: \"Acme Corp\"\n  subject: \"Interested in Enterprise plan\"\n```\n\n---\n\n### 2. Manage Accounts\n\nCreate and organize account (company) records in the CRM.\n\n**Tool:** `DYNAMICS365_DYNAMICSCRM_CREATE_ACCOUNT`\n\n**Key Parameters:**\n- `name` -- Account/company name\n- `description` -- Description of the account\n- `revenue` -- Revenue amount (number)\n- `accountcategorycode` -- Category code (integer, default: 1)\n- `creditonhold` -- Whether account is on credit hold (boolean)\n\n**Example:**\n```\nTool: DYNAMICS365_DYNAMICSCRM_CREATE_ACCOUNT\nArguments:\n  name: \"Contoso Ltd\"\n  description: \"Strategic partner for cloud services\"\n  revenue: 5000000\n  creditonhold: false\n```\n\n---\n\n### 3. Manage Contacts\n\nCreate detailed contact records with address and phone information.\n\n**Tool:** `DYNAMICS365_DYNAMICSCRM_CREATE_CONTACT`\n\n**Key Parameters:**\n- `firstname`, `lastname` -- Contact name\n- `emailaddress1` -- Primary email\n- `telephone1` -- Primary phone\n- `mobilephone` -- Mobile phone\n- `jobtitle` -- Job title\n- `address1_city`, `address1_stateorprovince`, `address1_postalcode`, `address1_country` -- Address fields\n\n**Example:**\n```\nTool: DYNAMICS365_DYNAMICSCRM_CREATE_CONTACT\nArguments:\n  firstname: \"Bob\"\n  lastname: \"Johnson\"\n  emailaddress1: \"bob.johnson@example.com\"\n  jobtitle: \"VP of Engineering\"\n  address1_city: \"Seattle\"\n  address1_stateorprovince: \"WA\"\n```\n\n---\n\n### 4. Manage Opportunities\n\nCreate and update sales opportunities with estimated values and close dates.\n\n**Tools:**\n- `DYNAMICS365_DYNAMICSCRM_CREATE_OPPORTUNITY` -- Create a new opportunity\n- `DYNAMICS365_DYNAMICSCRM_UPDATE_OPPORTUNITY` -- Update an existing opportunity\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_CREATE_OPPORTUNITY`:**\n- `name` (required) -- Opportunity title\n- `description` -- Brief description\n- `estimatedvalue` -- Anticipated revenue (number)\n- `estimatedclosedate` -- Expected close date in `YYYY-MM-DD` format\n- `customer_account_id` -- GUID of the related account (no curly braces)\n- `customer_contact_id` -- GUID of the related contact (no curly braces)\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_UPDATE_OPPORTUNITY`:**\n- `opportunity_id` (required) -- GUID of the opportunity\n- `opportunityratingcode` -- 1 (Cold), 2 (Warm), 3 (Hot)\n- `salesstagecode` -- 1 (Qualify), 2 (Develop), 3 (Propose)\n\n**Example:**\n```\nTool: DYNAMICS365_DYNAMICSCRM_CREATE_OPPORTUNITY\nArguments:\n  name: \"Enterprise Cloud Migration\"\n  estimatedvalue: 250000\n  estimatedclosedate: \"2026-06-30\"\n  description: \"Full cloud migration project for Contoso\"\n```\n\n---\n\n### 5. Manage Sales Orders and Invoices\n\nCreate and update sales orders; generate invoices for billing.\n\n**Tools:**\n- `DYNAMICS365_DYNAMICSCRM_CREATE_SALES_ORDER` -- Create a new sales order\n- `DYNAMICS365_DYNAMICSCRM_UPDATE_SALES_ORDER` -- Update an existing sales order\n- `DYNAMICS365_DYNAMICSCRM_CREATE_INVOICE` -- Create a new invoice\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_CREATE_SALES_ORDER`:**\n- `name` -- Sales order name\n- `description` -- Description\n- `account_id` -- Reference to account, format: `\"/accounts(GUID)\"`\n- `currency_id` -- Currency reference, format: `\"/transactioncurrencies(GUID)\"`\n- `price_level_id` -- Price list reference, format: `\"/pricelevels(GUID)\"`\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_UPDATE_SALES_ORDER`:**\n- `salesorder_id` (required) -- GUID of the sales order\n- `name` -- Updated name\n- `discountamount` -- Updated discount\n- `freightamount` -- Updated shipping cost\n\n**Key Parameters for `DYNAMICS365_DYNAMICSCRM_CREATE_INVOICE`:**\n- `name` -- Invoice name/number, e.g., `\"Invoice #12345\"`\n- `description` -- Invoice description\n- `account_id` -- Related account reference\n- `currency_id` -- Currency reference\n- `price_level_id` -- Price list reference\n\n---\n\n### 6. Create Support Cases\n\nCreate incident/case records for customer support tracking.\n\n**Tool:** `DYNAMICS365_DYNAMICSCRM_CREATE_CASE`\n\n**Key Parameters:**\n- `title` -- Subject/title of the case\n- `description` -- Detailed description\n- `prioritycode` -- 1 (Low), 2 (Normal), 3 (High)\n- `caseorigincode` -- 1 (Phone), 2 (Email), 3 (Web)\n- `account_id` -- Related account, format: `\"/accounts(GUID)\"`\n- `contact_id` -- Related contact, format: `\"/contacts(GUID)\"`\n\n**Example:**\n```\nTool: DYNAMICS365_DYNAMICSCRM_CREATE_CASE\nArguments:\n  title: \"Login issue reported by customer\"\n  description: \"Customer unable to access portal since Feb 10\"\n  prioritycode: 3\n  caseorigincode: 2\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **GUID format** | All entity IDs are GUIDs (e.g., `\"00000000-0000-0000-0000-000000000000\"`). Do not include curly braces for opportunity/contact references. |\n| **Reference format** | Related entity references use the format `\"/entityset(GUID)\"` (e.g., `\"/accounts(abc-123)\"`). Missing the leading slash or parentheses causes errors. |\n| **OData filter syntax** | Use Dynamics 365 OData syntax for `filter` (e.g., `contains(fullname,'John')`). Incorrect syntax returns empty or error responses. |\n| **user_id default** | Most tools default `user_id` to `\"me\"` for the authenticated user. Override only when acting on behalf of another user. |\n| **Required fields** | `CREATE_OPPORTUNITY` requires `name`. Other create tools have no strict required fields but will create empty records without data. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `DYNAMICS365_DYNAMICSCRM_CREATE_LEAD` | Create a new lead record |\n| `DYNAMICS365_DYNAMICSCRM_UPDATE_LEAD` | Update an existing lead |\n| `DYNAMICS365_DYNAMICSCRM_GET_A_LEAD` | Retrieve a lead by GUID |\n| `DYNAMICS365_DYNAMICSCRM_GET_ALL_LEADS` | List/filter all leads |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_ACCOUNT` | Create a new account |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_CONTACT` | Create a new contact |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_OPPORTUNITY` | Create a new opportunity |\n| `DYNAMICS365_DYNAMICSCRM_UPDATE_OPPORTUNITY` | Update an existing opportunity |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_SALES_ORDER` | Create a new sales order |\n| `DYNAMICS365_DYNAMICSCRM_UPDATE_SALES_ORDER` | Update an existing sales order |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_INVOICE` | Create a new invoice |\n| `DYNAMICS365_DYNAMICSCRM_CREATE_CASE` | Create a support case/incident |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/echtpost-automation/SKILL.md",
    "content": "---\nname: echtpost-automation\ndescription: \"Automate Echtpost tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Echtpost Automation via Rube MCP\n\nAutomate Echtpost operations through Composio's Echtpost toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/echtpost](https://composio.dev/toolkits/echtpost)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Echtpost connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `echtpost`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `echtpost`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Echtpost operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Echtpost task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"echtpost\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Echtpost-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `echtpost` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/elevenlabs-automation/SKILL.md",
    "content": "---\nname: ElevenLabs Automation\ndescription: \"Automate ElevenLabs text-to-speech workflows -- generate speech from text, browse and inspect voices, check subscription limits, list models, stream audio, and retrieve history via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# ElevenLabs Automation\n\nAutomate your ElevenLabs text-to-speech workflows -- convert text to natural speech, browse the voice library, inspect voice details, check subscription credits, select TTS models, stream audio for low-latency delivery, and retrieve previously generated audio from history.\n\n**Toolkit docs:** [composio.dev/toolkits/elevenlabs](https://composio.dev/toolkits/elevenlabs)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your ElevenLabs account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. Generate Speech from Text\n\nUse `ELEVENLABS_TEXT_TO_SPEECH` to convert text into a downloadable audio file.\n\n```\nTool: ELEVENLABS_TEXT_TO_SPEECH\nInputs:\n  - voice_id: string (required) -- obtain from ELEVENLABS_GET_VOICES\n  - text: string (required) -- max ~10,000 chars (most models), 30,000 (Flash/Turbo v2), 40,000 (v2.5)\n  - model_id: string (default \"eleven_monolingual_v1\") -- e.g., \"eleven_multilingual_v2\"\n  - output_format: string (default \"mp3_44100_128\") -- see formats below\n  - optimize_streaming_latency: integer (0-4; NOT supported with eleven_v3)\n  - seed: integer (optional, for reproducibility -- not guaranteed)\n  - pronunciation_dictionary_locators: array (optional, up to 3 dictionaries)\n```\n\n**Output formats:**\n- MP3: `mp3_22050_32`, `mp3_44100_32`, `mp3_44100_64`, `mp3_44100_96`, `mp3_44100_128`, `mp3_44100_192` (Creator+)\n- PCM: `pcm_16000`, `pcm_22050`, `pcm_24000`, `pcm_44100` (Pro+)\n- uLaw: `ulaw_8000` (for Twilio)\n\n**Important:** Output is a file object with a presigned download link at `data.file.s3url` (expires in ~1 hour). Download promptly.\n\n### 2. Browse Available Voices\n\nUse `ELEVENLABS_GET_VOICES` to list all voices with their attributes and settings.\n\n```\nTool: ELEVENLABS_GET_VOICES\nInputs: (none)\n```\n\nReturns an array at `data.voices[]` with `voice_id`, `name`, `labels` (gender, accent, use_case), and settings.\n\n### 3. Inspect a Specific Voice\n\nUse `ELEVENLABS_GET_VOICE` to get detailed metadata for a candidate voice before synthesis.\n\n```\nTool: ELEVENLABS_GET_VOICE\nInputs:\n  - voice_id: string (required) -- e.g., \"21m00Tcm4TlvDq8ikWAM\"\n  - with_settings: boolean (default false) -- include detailed voice settings\n```\n\n### 4. Check Subscription and Credits\n\nUse `ELEVENLABS_GET_USER_SUBSCRIPTION_INFO` to verify plan limits and remaining credits before bulk generation.\n\n```\nTool: ELEVENLABS_GET_USER_SUBSCRIPTION_INFO\nInputs: (none)\n```\n\n### 5. List Available TTS Models\n\nUse `ELEVENLABS_GET_MODELS` to discover compatible models and filter by `can_do_text_to_speech: true`.\n\n```\nTool: ELEVENLABS_GET_MODELS\nInputs: (none)\n```\n\n### 6. Stream Audio and Retrieve History\n\nUse `ELEVENLABS_TEXT_TO_SPEECH_STREAM` for low-latency streamed delivery, and `ELEVENLABS_GET_AUDIO_FROM_HISTORY_ITEM` to re-download previously generated audio.\n\n```\nTool: ELEVENLABS_TEXT_TO_SPEECH_STREAM\n  - Same core inputs as TEXT_TO_SPEECH but returns a stream for low-latency playback\n\nTool: ELEVENLABS_GET_AUDIO_FROM_HISTORY_ITEM\n  - history_item_id: string (required) -- ID from a previous generation\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Text length limits | Most models cap at ~10,000-20,000 chars per request. Oversized input returns HTTP 400. Split long text into chunks (~5000 chars) and generate per chunk. |\n| Output is a presigned URL | `ELEVENLABS_TEXT_TO_SPEECH` returns `data.file.s3url` with a ~1 hour expiry (X-Amz-Expires=3600). Download the audio file promptly. |\n| Quota and credit errors | HTTP 401 with `quota_exceeded` or HTTP 402 `payment_required` means insufficient credits or tier restrictions. Check with `ELEVENLABS_GET_USER_SUBSCRIPTION_INFO` before bulk jobs. |\n| Voice permissions | HTTP 401 with `missing_permissions` means the API key lacks `voices_read` scope. Verify key permissions. |\n| Model compatibility | Not all models support TTS. Use `ELEVENLABS_GET_MODELS` and filter by `can_do_text_to_speech: true`. The `optimize_streaming_latency` parameter is NOT supported with `eleven_v3`. |\n| Large voice list truncation | `ELEVENLABS_GET_VOICES` may return a large list. Select from the full `data.voices[]` payload -- previews may appear truncated. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `ELEVENLABS_TEXT_TO_SPEECH` | Convert text to speech, returns downloadable audio file |\n| `ELEVENLABS_GET_VOICES` | List all available voices with attributes |\n| `ELEVENLABS_GET_VOICE` | Get detailed info for a specific voice |\n| `ELEVENLABS_GET_USER_SUBSCRIPTION_INFO` | Check subscription plan and remaining credits |\n| `ELEVENLABS_GET_MODELS` | List available TTS models and capabilities |\n| `ELEVENLABS_TEXT_TO_SPEECH_STREAM` | Stream audio for low-latency delivery |\n| `ELEVENLABS_GET_AUDIO_FROM_HISTORY_ITEM` | Re-download audio from generation history |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/elorus-automation/SKILL.md",
    "content": "---\nname: elorus-automation\ndescription: \"Automate Elorus tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Elorus Automation via Rube MCP\n\nAutomate Elorus operations through Composio's Elorus toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/elorus](https://composio.dev/toolkits/elorus)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Elorus connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `elorus`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `elorus`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Elorus operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Elorus task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"elorus\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Elorus-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `elorus` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/emailable-automation/SKILL.md",
    "content": "---\nname: emailable-automation\ndescription: \"Automate Emailable tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Emailable Automation via Rube MCP\n\nAutomate Emailable operations through Composio's Emailable toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/emailable](https://composio.dev/toolkits/emailable)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Emailable connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `emailable`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `emailable`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Emailable operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Emailable task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"emailable\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Emailable-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `emailable` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/emaillistverify-automation/SKILL.md",
    "content": "---\nname: emaillistverify-automation\ndescription: \"Automate Emaillistverify tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Emaillistverify Automation via Rube MCP\n\nAutomate Emaillistverify operations through Composio's Emaillistverify toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/emaillistverify](https://composio.dev/toolkits/emaillistverify)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Emaillistverify connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `emaillistverify`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `emaillistverify`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Emaillistverify operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Emaillistverify task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"emaillistverify\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Emaillistverify-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `emaillistverify` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/emailoctopus-automation/SKILL.md",
    "content": "---\nname: emailoctopus-automation\ndescription: \"Automate Emailoctopus tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Emailoctopus Automation via Rube MCP\n\nAutomate Emailoctopus operations through Composio's Emailoctopus toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/emailoctopus](https://composio.dev/toolkits/emailoctopus)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Emailoctopus connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `emailoctopus`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `emailoctopus`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Emailoctopus operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Emailoctopus task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"emailoctopus\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Emailoctopus-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `emailoctopus` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/emelia-automation/SKILL.md",
    "content": "---\nname: emelia-automation\ndescription: \"Automate Emelia tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Emelia Automation via Rube MCP\n\nAutomate Emelia operations through Composio's Emelia toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/emelia](https://composio.dev/toolkits/emelia)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Emelia connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `emelia`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `emelia`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Emelia operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Emelia task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"emelia\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Emelia-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `emelia` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/encodian-automation/SKILL.md",
    "content": "---\nname: encodian-automation\ndescription: \"Automate Encodian tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Encodian Automation via Rube MCP\n\nAutomate Encodian operations through Composio's Encodian toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/encodian](https://composio.dev/toolkits/encodian)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Encodian connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `encodian`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `encodian`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Encodian operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Encodian task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"encodian\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Encodian-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `encodian` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/endorsal-automation/SKILL.md",
    "content": "---\nname: endorsal-automation\ndescription: \"Automate Endorsal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Endorsal Automation via Rube MCP\n\nAutomate Endorsal operations through Composio's Endorsal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/endorsal](https://composio.dev/toolkits/endorsal)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Endorsal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `endorsal`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `endorsal`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Endorsal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Endorsal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"endorsal\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Endorsal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `endorsal` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/enginemailer-automation/SKILL.md",
    "content": "---\nname: enginemailer-automation\ndescription: \"Automate Enginemailer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Enginemailer Automation via Rube MCP\n\nAutomate Enginemailer operations through Composio's Enginemailer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/enginemailer](https://composio.dev/toolkits/enginemailer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Enginemailer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `enginemailer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `enginemailer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Enginemailer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Enginemailer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"enginemailer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Enginemailer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `enginemailer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/enigma-automation/SKILL.md",
    "content": "---\nname: enigma-automation\ndescription: \"Automate Enigma tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Enigma Automation via Rube MCP\n\nAutomate Enigma operations through Composio's Enigma toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/enigma](https://composio.dev/toolkits/enigma)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Enigma connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `enigma`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `enigma`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Enigma operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Enigma task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"enigma\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Enigma-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `enigma` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/entelligence-automation/SKILL.md",
    "content": "---\nname: entelligence-automation\ndescription: \"Automate Entelligence tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Entelligence Automation via Rube MCP\n\nAutomate Entelligence operations through Composio's Entelligence toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/entelligence](https://composio.dev/toolkits/entelligence)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Entelligence connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `entelligence`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `entelligence`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Entelligence operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Entelligence task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"entelligence\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Entelligence-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `entelligence` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/eodhd-apis-automation/SKILL.md",
    "content": "---\nname: eodhd-apis-automation\ndescription: \"Automate Eodhd Apis tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Eodhd Apis Automation via Rube MCP\n\nAutomate Eodhd Apis operations through Composio's Eodhd Apis toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/eodhd_apis](https://composio.dev/toolkits/eodhd_apis)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Eodhd Apis connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `eodhd_apis`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `eodhd_apis`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Eodhd Apis operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Eodhd Apis task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"eodhd_apis\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Eodhd Apis-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `eodhd_apis` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/epic-games-automation/SKILL.md",
    "content": "---\nname: epic-games-automation\ndescription: \"Automate Epic Games tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Epic Games Automation via Rube MCP\n\nAutomate Epic Games operations through Composio's Epic Games toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/epic_games](https://composio.dev/toolkits/epic_games)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Epic Games connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `epic_games`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `epic_games`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Epic Games operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Epic Games task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"epic_games\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Epic Games-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `epic_games` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/esignatures-io-automation/SKILL.md",
    "content": "---\nname: esignatures-io-automation\ndescription: \"Automate Esignatures IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Esignatures IO Automation via Rube MCP\n\nAutomate Esignatures IO operations through Composio's Esignatures IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/esignatures_io](https://composio.dev/toolkits/esignatures_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Esignatures IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `esignatures_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `esignatures_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Esignatures IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Esignatures IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"esignatures_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Esignatures IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `esignatures_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/espocrm-automation/SKILL.md",
    "content": "---\nname: espocrm-automation\ndescription: \"Automate Espocrm tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Espocrm Automation via Rube MCP\n\nAutomate Espocrm operations through Composio's Espocrm toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/espocrm](https://composio.dev/toolkits/espocrm)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Espocrm connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `espocrm`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `espocrm`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Espocrm operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Espocrm task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"espocrm\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Espocrm-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `espocrm` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/esputnik-automation/SKILL.md",
    "content": "---\nname: esputnik-automation\ndescription: \"Automate Esputnik tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Esputnik Automation via Rube MCP\n\nAutomate Esputnik operations through Composio's Esputnik toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/esputnik](https://composio.dev/toolkits/esputnik)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Esputnik connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `esputnik`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `esputnik`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Esputnik operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Esputnik task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"esputnik\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Esputnik-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `esputnik` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/etermin-automation/SKILL.md",
    "content": "---\nname: etermin-automation\ndescription: \"Automate Etermin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Etermin Automation via Rube MCP\n\nAutomate Etermin operations through Composio's Etermin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/etermin](https://composio.dev/toolkits/etermin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Etermin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `etermin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `etermin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Etermin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Etermin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"etermin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Etermin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `etermin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/evenium-automation/SKILL.md",
    "content": "---\nname: evenium-automation\ndescription: \"Automate Evenium tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Evenium Automation via Rube MCP\n\nAutomate Evenium operations through Composio's Evenium toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/evenium](https://composio.dev/toolkits/evenium)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Evenium connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `evenium`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `evenium`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Evenium operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Evenium task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"evenium\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Evenium-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `evenium` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/eventbrite-automation/SKILL.md",
    "content": "---\nname: Eventbrite Automation\ndescription: \"Automate Eventbrite event management, attendee tracking, organization discovery, and category browsing through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Eventbrite Automation\n\nAutomate Eventbrite event management workflows -- list organization events, track attendees, browse categories and formats, and manage organizations -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/eventbrite](https://composio.dev/toolkits/eventbrite)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Eventbrite account when prompted (OAuth flow via Composio)\n3. Start issuing natural language commands for Eventbrite automation\n\n---\n\n## Core Workflows\n\n### 1. Discover Your Organizations\n\nRetrieve the organizations the authenticated user belongs to. This is a prerequisite for most other Eventbrite operations since `organization_id` is required.\n\n**Tool:** `EVENTBRITE_LIST_USER_ORGANIZATIONS`\n\nNo parameters required. Returns organization IDs, names, and metadata.\n\n> Always call this first to obtain the `organization_id` needed by event and attendee endpoints.\n\nExample prompt:\n> \"List my Eventbrite organizations\"\n\n---\n\n### 2. List and Search Organization Events\n\nBrowse events owned by a specific organization with filtering by status, time period, and pagination.\n\n**Tool:** `EVENTBRITE_LIST_ORGANIZATION_EVENTS`\n\nKey parameters:\n- `organization_id` -- the organization whose events to list (required; get from `EVENTBRITE_LIST_USER_ORGANIZATIONS`)\n- `status` -- filter by `live`, `draft`, `canceled`, `started`, `ended`, `completed`, or `all`\n- `time_filter` -- filter by `current_future` or `past`\n- `order_by` -- sort by `start_asc`, `start_desc`, `created_asc`, `created_desc`, `name_asc`, `name_desc`\n- `page_size` -- number of events per page\n- `continuation` -- pagination token from previous response\n- `expand` -- comma-separated fields to expand: `organizer`, `venue`, `ticket_classes`\n\nExample prompt:\n> \"Show me all live events for my organization, sorted by start date\"\n\n---\n\n### 3. Track Event Attendees\n\nRetrieve the attendee list for any event, with optional status filtering and pagination.\n\n**Tool:** `EVENTBRITE_LIST_EVENT_ATTENDEES`\n\nKey parameters:\n- `event_id` -- the event to retrieve attendees for (required)\n- `status` -- filter by `attending`, `not_attending`, or `cancelled`\n- `changed_since` -- ISO 8601 timestamp to get only recently changed attendees\n- `continuation` -- pagination token for subsequent pages\n\nExample prompt:\n> \"Get all attending attendees for event 123456789 who changed since January 1st\"\n\n---\n\n### 4. Browse Event Categories\n\nRetrieve available event categories for use when creating or filtering events.\n\n**Tool:** `EVENTBRITE_GET_EVENT_CATEGORIES`\n\nKey parameters:\n- `locale` -- BCP-47 locale for localized names (e.g., `en_US`, `es_ES`)\n\nFollow up with `EVENTBRITE_GET_EVENT_SUBCATEGORIES` to get subcategories within a selected category.\n\nExample prompt:\n> \"List all Eventbrite event categories in English\"\n\n---\n\n### 5. List Event Formats\n\nRetrieve all available event format types (conference, seminar, workshop, etc.).\n\n**Tool:** `EVENTBRITE_GET_EVENT_FORMATS`\n\nNo parameters required. Returns format IDs and display names.\n\nExample prompt:\n> \"What event formats are available on Eventbrite?\"\n\n---\n\n### 6. Browse Event Subcategories\n\nRetrieve subcategories for more granular event classification.\n\n**Tool:** `EVENTBRITE_GET_EVENT_SUBCATEGORIES`\n\nKey parameters:\n- `locale` -- BCP-47 locale for localized names (e.g., `en_US`)\n\nExample prompt:\n> \"List all Eventbrite event subcategories\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Organization ID required | Most event operations require `organization_id` -- always call `EVENTBRITE_LIST_USER_ORGANIZATIONS` first |\n| Pagination via continuation | Results use continuation-token pagination, not page numbers -- pass the `continuation` value from the previous response to get the next page |\n| Event ID discovery | You need to list events first via `EVENTBRITE_LIST_ORGANIZATION_EVENTS` to get `event_id` values for attendee queries |\n| Status values are specific | Event status values (`live`, `draft`, `canceled`, `started`, `ended`, `completed`) must match exactly |\n| Expand fields are comma-separated | The `expand` parameter takes a comma-separated string, not an array (e.g., `\"organizer,venue\"`) |\n| changed_since format | The `changed_since` parameter must be in ISO 8601 format (e.g., `2024-01-01T00:00:00Z`) |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| List organizations | `EVENTBRITE_LIST_USER_ORGANIZATIONS` | (none) |\n| List events | `EVENTBRITE_LIST_ORGANIZATION_EVENTS` | `organization_id`, `status`, `time_filter` |\n| List attendees | `EVENTBRITE_LIST_EVENT_ATTENDEES` | `event_id`, `status`, `changed_since` |\n| Get categories | `EVENTBRITE_GET_EVENT_CATEGORIES` | `locale` |\n| Get subcategories | `EVENTBRITE_GET_EVENT_SUBCATEGORIES` | `locale` |\n| Get formats | `EVENTBRITE_GET_EVENT_FORMATS` | (none) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/eventee-automation/SKILL.md",
    "content": "---\nname: eventee-automation\ndescription: \"Automate Eventee tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Eventee Automation via Rube MCP\n\nAutomate Eventee operations through Composio's Eventee toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/eventee](https://composio.dev/toolkits/eventee)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Eventee connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `eventee`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `eventee`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Eventee operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Eventee task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"eventee\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Eventee-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `eventee` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/eventzilla-automation/SKILL.md",
    "content": "---\nname: eventzilla-automation\ndescription: \"Automate Eventzilla tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Eventzilla Automation via Rube MCP\n\nAutomate Eventzilla operations through Composio's Eventzilla toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/eventzilla](https://composio.dev/toolkits/eventzilla)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Eventzilla connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `eventzilla`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `eventzilla`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Eventzilla operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Eventzilla task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"eventzilla\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Eventzilla-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `eventzilla` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/everhour-automation/SKILL.md",
    "content": "---\nname: everhour-automation\ndescription: \"Automate Everhour tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Everhour Automation via Rube MCP\n\nAutomate Everhour operations through Composio's Everhour toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/everhour](https://composio.dev/toolkits/everhour)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Everhour connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `everhour`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `everhour`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Everhour operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Everhour task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"everhour\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Everhour-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `everhour` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/eversign-automation/SKILL.md",
    "content": "---\nname: eversign-automation\ndescription: \"Automate Eversign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Eversign Automation via Rube MCP\n\nAutomate Eversign operations through Composio's Eversign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/eversign](https://composio.dev/toolkits/eversign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Eversign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `eversign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `eversign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Eversign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Eversign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"eversign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Eversign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `eversign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/exa-automation/SKILL.md",
    "content": "---\nname: exa-automation\ndescription: \"Automate Exa tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Exa Automation via Rube MCP\n\nAutomate Exa operations through Composio's Exa toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/exa](https://composio.dev/toolkits/exa)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Exa connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `exa`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `exa`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Exa operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Exa task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"exa\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Exa-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `exa` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/excel-automation/SKILL.md",
    "content": "---\nname: Excel Automation\ndescription: \"Excel Automation: create workbooks, manage worksheets, read/write cell data, and format spreadsheets via Microsoft Excel and Google Sheets integration\"\nrequires:\n  mcp: [rube]\n---\n\n# Excel Automation\n\nAutomate spreadsheet operations including creating workbooks, writing data, formatting cells, upserting rows, and managing worksheets. Works with Microsoft Excel (OneDrive) and Google Sheets.\n\n**Toolkit docs:** [composio.dev/toolkits/excel](https://composio.dev/toolkits/excel)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `excel` (and optionally `googlesheets`) toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. Create a New Excel Workbook\n\nUse `EXCEL_CREATE_WORKBOOK` to generate a new `.xlsx` file and upload it to OneDrive.\n\n**Tool:** `EXCEL_CREATE_WORKBOOK`\n\n**Steps:**\n1. Call `EXCEL_CREATE_WORKBOOK` with worksheet names and data\n2. The tool creates a `.xlsx` file and uploads it to OneDrive\n3. Use the returned file path/URL for subsequent operations\n\n---\n\n### 2. Write Data to a Spreadsheet\n\nUse `GOOGLESHEETS_BATCH_UPDATE` to write values to a specific range or append rows.\n\n**Tool:** `GOOGLESHEETS_BATCH_UPDATE`\n\n**Key Parameters:**\n- `spreadsheet_id` (required) -- The spreadsheet ID from the URL (44-char alphanumeric string)\n- `sheet_name` (required) -- Tab name, e.g., `\"Sheet1\"`, `\"Sales Data\"`\n- `values` (required) -- 2D array of cell values, e.g., `[[\"Name\",\"Amount\"],[\"Alice\",100]]`\n- `first_cell_location` -- Starting cell in A1 notation (e.g., `\"A1\"`, `\"D3\"`). Omit to append rows\n- `valueInputOption` -- `\"USER_ENTERED\"` (default, parses formulas) or `\"RAW\"` (stores as-is)\n\n**Example:**\n```\nTool: GOOGLESHEETS_BATCH_UPDATE\nArguments:\n  spreadsheet_id: \"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\"\n  sheet_name: \"Sheet1\"\n  values: [[\"Item\",\"Cost\",\"Stocked\"],[\"Wheel\",20.50,true],[\"Screw\",0.50,true]]\n  first_cell_location: \"A1\"\n```\n\n---\n\n### 3. Upsert Rows by Key Column\n\nUse `GOOGLESHEETS_UPSERT_ROWS` to update existing rows by matching a key column, or append new rows if no match is found. Ideal for CRM syncs, inventory updates, and deduplication.\n\n**Tool:** `GOOGLESHEETS_UPSERT_ROWS`\n\n**Key Parameters:**\n- `spreadsheetId` (required) -- The spreadsheet ID\n- `sheetName` (required) -- Tab name\n- `rows` (required) -- 2D array of data rows (min 1 row). If `headers` is omitted, the first row is treated as headers\n- `headers` -- Column names for the data, e.g., `[\"Email\",\"Phone\",\"Status\"]`\n- `keyColumn` -- Column header to match on, e.g., `\"Email\"`, `\"SKU\"`, `\"Lead ID\"`\n- `strictMode` -- `true` (default) errors on mismatched columns; `false` truncates silently\n\n**Example:**\n```\nTool: GOOGLESHEETS_UPSERT_ROWS\nArguments:\n  spreadsheetId: \"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\"\n  sheetName: \"Contacts\"\n  keyColumn: \"Email\"\n  headers: [\"Email\",\"Phone\",\"Status\"]\n  rows: [[\"john@example.com\",\"555-0101\",\"Active\"],[\"jane@example.com\",\"555-0102\",\"Pending\"]]\n```\n\n---\n\n### 4. Format Cells\n\nUse `GOOGLESHEETS_FORMAT_CELL` to apply bold, italic, font size, and background colors to ranges.\n\n**Tool:** `GOOGLESHEETS_FORMAT_CELL`\n\n**Key Parameters:**\n- `spreadsheet_id` (required) -- The spreadsheet ID\n- `range` -- Cell range in A1 notation, e.g., `\"A1:D1\"`, `\"B2:B10\"` (recommended over index-based)\n- `sheet_name` -- Worksheet name, e.g., `\"Sheet1\"`\n- `bold` -- `true`/`false`\n- `italic` -- `true`/`false`\n- `fontSize` -- Font size in points, e.g., `12`\n- `red`, `green`, `blue` -- Background color components (0.0--1.0 float scale, NOT 0--255)\n\n**Example (bold header row with blue background):**\n```\nTool: GOOGLESHEETS_FORMAT_CELL\nArguments:\n  spreadsheet_id: \"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\"\n  range: \"A1:D1\"\n  sheet_name: \"Sheet1\"\n  bold: true\n  fontSize: 12\n  red: 0.2\n  green: 0.4\n  blue: 0.9\n```\n\n---\n\n### 5. Add New Worksheet Tabs\n\nUse `GOOGLESHEETS_ADD_SHEET` to create new tabs within an existing spreadsheet.\n\n**Tool:** `GOOGLESHEETS_ADD_SHEET`\n\n**Key Parameters:**\n- `spreadsheetId` (required) -- The spreadsheet ID\n- `title` -- Name for the new tab, e.g., `\"Q4 Report\"`\n- `forceUnique` -- `true` (default) auto-appends suffix if name exists\n\n**Example:**\n```\nTool: GOOGLESHEETS_ADD_SHEET\nArguments:\n  spreadsheetId: \"1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\"\n  title: \"Q4 Report\"\n  forceUnique: true\n```\n\n---\n\n### 6. Read Data and Verify Content\n\nUse `GOOGLESHEETS_BATCH_GET` to retrieve data from specified cell ranges for validation or further processing.\n\n**Tool:** `GOOGLESHEETS_BATCH_GET`\n\n**Steps:**\n1. Call `GOOGLESHEETS_BATCH_GET` with the spreadsheet ID and target ranges\n2. Validate headers and data alignment\n3. Use results to inform subsequent write or update operations\n\n**Supporting Tools:**\n- `GOOGLESHEETS_GET_SHEET_NAMES` -- List all tab names in a spreadsheet\n- `GOOGLESHEETS_GET_SPREADSHEET_INFO` -- Get metadata (sheet IDs, properties)\n- `GOOGLESHEETS_FIND_WORKSHEET_BY_TITLE` -- Check if a specific tab exists\n\n---\n\n## Recommended Execution Plan\n\n1. **Create or locate the spreadsheet** using `GOOGLESHEETS_CREATE_GOOGLE_SHEET1` or reuse an existing `spreadsheetId`\n2. **Confirm the destination tab** using `GOOGLESHEETS_GET_SHEET_NAMES` or `GOOGLESHEETS_FIND_WORKSHEET_BY_TITLE`; create it with `GOOGLESHEETS_ADD_SHEET` if missing\n3. **Read existing headers** (optional) using `GOOGLESHEETS_BATCH_GET` to align columns\n4. **Write or upsert data** using `GOOGLESHEETS_BATCH_UPDATE` or `GOOGLESHEETS_UPSERT_ROWS`\n5. **Apply formatting** (optional) using `GOOGLESHEETS_FORMAT_CELL`\n6. **Verify results** (optional) using `GOOGLESHEETS_BATCH_GET`\n7. **Fallback:** If Google Sheets creation is blocked (HTTP 403), use `EXCEL_CREATE_WORKBOOK` for local `.xlsx` output\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **HTTP 403 on sheet creation** | `GOOGLESHEETS_CREATE_GOOGLE_SHEET1` fails when Drive create scope is missing. Reuse an existing `spreadsheetId` or fall back to `EXCEL_CREATE_WORKBOOK`. |\n| **Cell limit and rate throttling** | Google Sheets has a ~5,000,000 cell limit per spreadsheet. Excessive write frequency triggers HTTP 429. Batch changes and chunk large writes (~500 rows/call). |\n| **Format range off-by-one** | `GOOGLESHEETS_FORMAT_CELL` uses 0-based, endIndex-exclusive ranges when using index mode. Background color uses 0--1 float RGB, NOT 0--255 integer RGB. |\n| **Sheet title uniqueness** | Sheet titles are not guaranteed unique across API responses. Prefer operating by numeric `sheetId` and verify the resolved tab before writing. |\n| **Upsert payload shape** | `GOOGLESHEETS_UPSERT_ROWS` requires headers + 2D rows array. Sending list-of-dicts or empty `rows` causes validation errors. Ensure at least 1 data row. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `EXCEL_CREATE_WORKBOOK` | Create a new `.xlsx` workbook and upload to OneDrive |\n| `GOOGLESHEETS_BATCH_UPDATE` | Write values to a range or append new rows |\n| `GOOGLESHEETS_UPSERT_ROWS` | Update existing rows by key or append new ones |\n| `GOOGLESHEETS_FORMAT_CELL` | Apply text/background formatting to cell ranges |\n| `GOOGLESHEETS_ADD_SHEET` | Add a new worksheet tab to a spreadsheet |\n| `GOOGLESHEETS_CREATE_GOOGLE_SHEET1` | Create a new Google Spreadsheet in Drive |\n| `GOOGLESHEETS_GET_SHEET_NAMES` | List all worksheet names in a spreadsheet |\n| `GOOGLESHEETS_GET_SPREADSHEET_INFO` | Retrieve spreadsheet metadata |\n| `GOOGLESHEETS_FIND_WORKSHEET_BY_TITLE` | Check if a worksheet exists by title |\n| `GOOGLESHEETS_BATCH_GET` | Read data from specified cell ranges |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/exist-automation/SKILL.md",
    "content": "---\nname: exist-automation\ndescription: \"Automate Exist tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Exist Automation via Rube MCP\n\nAutomate Exist operations through Composio's Exist toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/exist](https://composio.dev/toolkits/exist)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Exist connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `exist`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `exist`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Exist operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Exist task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"exist\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Exist-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `exist` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/expofp-automation/SKILL.md",
    "content": "---\nname: expofp-automation\ndescription: \"Automate Expofp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Expofp Automation via Rube MCP\n\nAutomate Expofp operations through Composio's Expofp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/expofp](https://composio.dev/toolkits/expofp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Expofp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `expofp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `expofp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Expofp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Expofp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"expofp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Expofp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `expofp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/extracta-ai-automation/SKILL.md",
    "content": "---\nname: extracta-ai-automation\ndescription: \"Automate Extracta AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Extracta AI Automation via Rube MCP\n\nAutomate Extracta AI operations through Composio's Extracta AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/extracta_ai](https://composio.dev/toolkits/extracta_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Extracta AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `extracta_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `extracta_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Extracta AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Extracta AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"extracta_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Extracta AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `extracta_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/facebook-automation/SKILL.md",
    "content": "---\nname: Facebook Automation\ndescription: \"Automate Facebook Page management including post creation, scheduling, video uploads, Messenger conversations, and audience engagement via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Facebook Automation\n\nAutomate Facebook Page operations -- create and schedule posts, upload videos, manage Messenger conversations, retrieve page insights, and handle scheduled content -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/facebook](https://composio.dev/toolkits/facebook)\n\n---\n\n## Setup\n\n1. Connect your Facebook account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `FACEBOOK_*` tools become available for execution\n4. **Note:** This toolkit supports Facebook Pages only, not personal Facebook accounts\n\n---\n\n## Core Workflows\n\n### 1. Discover Managed Pages\nList all Facebook Pages you manage to get page IDs and access tokens for subsequent operations.\n\n**Tool:** `FACEBOOK_LIST_MANAGED_PAGES`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fields` | string | No | Comma-separated fields (default: `id,name,access_token,category,tasks,about,link,picture`) |\n| `limit` | integer | No | Max pages per request (default: 25) |\n| `user_id` | string | No | User ID (default: `me`) |\n\n**Always run this first** to cache `page_id` values. Avoid repeating discovery calls -- cache the results.\n\n---\n\n### 2. Create & Schedule Posts\nPublish or schedule text posts with optional links on a Facebook Page.\n\n**Tool:** `FACEBOOK_CREATE_POST`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `page_id` | string | Yes | Numeric Page ID from managed pages |\n| `message` | string | Yes | Text content of the post |\n| `published` | boolean | No | `true` to publish immediately, `false` for draft/scheduled (default: true) |\n| `scheduled_publish_time` | integer | No | Unix UTC timestamp; must be at least 10 minutes in the future |\n| `link` | string | No | URL to include in the post |\n| `targeting` | object | No | Audience targeting specifications |\n\n**When scheduling:** Set `published=false` and provide `scheduled_publish_time` as a Unix UTC timestamp.\n\n---\n\n### 3. Create & Schedule Video Posts\nUpload and schedule video content on a Facebook Page.\n\n**Tool:** `FACEBOOK_CREATE_VIDEO_POST`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `page_id` | string | Yes | Numeric Page ID |\n| `file_url` | string | Conditional | URL of the video file (provide `file_url` or `video`) |\n| `video` | object | Conditional | Local file upload with `name`, `mimetype`, `s3key` |\n| `title` | string | No | Video title |\n| `description` | string | No | Video description |\n| `published` | boolean | No | Publish immediately (default: true) |\n| `scheduled_publish_time` | integer | No | Unix timestamp for scheduled publishing |\n\n---\n\n### 4. Manage Scheduled Posts\nReview, reschedule, update, or publish scheduled content.\n\n**Tools:**\n\n- **`FACEBOOK_GET_SCHEDULED_POSTS`** -- List scheduled/unpublished posts for a page\n  - `page_id` (required), `fields`, `limit` (max 100)\n- **`FACEBOOK_RESCHEDULE_POST`** -- Change the scheduled publish time\n- **`FACEBOOK_UPDATE_POST`** -- Edit caption/text on an existing post\n- **`FACEBOOK_PUBLISH_SCHEDULED_POST`** -- Publish a scheduled post immediately\n\n---\n\n### 5. Read Page Messenger Conversations\nRetrieve inbox conversations and message threads between users and your Page.\n\n**Tool:** `FACEBOOK_GET_PAGE_CONVERSATIONS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `page_id` | string | Yes | The Facebook Page ID |\n| `fields` | string | No | Fields to return (default: `participants,updated_time,id`) |\n| `limit` | integer | No | Conversations to return, max 25 |\n\nThen retrieve full message threads:\n\n**Tool:** `FACEBOOK_GET_CONVERSATION_MESSAGES`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `page_id` | string | Yes | Page ID that owns the conversation |\n| `conversation_id` | string | Yes | Conversation ID in `t_` format (e.g., `t_3638640842939952`) |\n| `fields` | string | No | Default: `id,created_time,from,to,message` |\n| `limit` | integer | No | Messages to return, max 25 |\n\n---\n\n### 6. Send Messages & Mark as Seen\nRespond to users via Messenger and mark messages as read.\n\n**Tools:**\n\n- **`FACEBOOK_SEND_MESSAGE`** -- Send a text message from the Page to a user via Messenger\n- **`FACEBOOK_MARK_MESSAGE_SEEN`** -- Mark a user's message as seen by the Page\n\n**Warning:** Both tools cause user-visible side effects. Only call after explicit confirmation.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Scheduling too close to now** | `FACEBOOK_CREATE_POST` with `scheduled_publish_time` less than ~10 minutes in the future returns HTTP 400 -- enforce a larger buffer for bulk runs |\n| **Unix UTC timestamps required** | `scheduled_publish_time` must be Unix UTC -- timezone conversion mistakes cause off-by-hours scheduling or validation failures |\n| **Cursor-based pagination** | `FACEBOOK_GET_SCHEDULED_POSTS` and `FACEBOOK_GET_PAGE_CONVERSATIONS` return subsets -- follow paging cursors to get complete data |\n| **Large conversation payloads** | Requesting embedded messages in conversations creates huge payloads -- use `FACEBOOK_GET_CONVERSATION_MESSAGES` for full threads instead |\n| **Video processing delays** | Uploaded videos may remain in processing state -- only schedule via `FACEBOOK_CREATE_VIDEO_POST` after the upload is usable |\n| **Cache page IDs** | Repeating `FACEBOOK_LIST_MANAGED_PAGES` calls adds latency -- cache `page_id` per workspace/run |\n| **Pages only** | This toolkit does not support personal Facebook accounts -- only Facebook Pages |\n| **Write operations need confirmation** | `FACEBOOK_SEND_MESSAGE` and `FACEBOOK_MARK_MESSAGE_SEEN` cause user-visible side effects -- only call after explicit user confirmation |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `FACEBOOK_LIST_MANAGED_PAGES` | List Pages you manage with access tokens |\n| `FACEBOOK_GET_PAGE_DETAILS` | Get detailed info about a specific Page |\n| `FACEBOOK_CREATE_POST` | Create or schedule a text/link post |\n| `FACEBOOK_CREATE_VIDEO_POST` | Create or schedule a video post |\n| `FACEBOOK_GET_SCHEDULED_POSTS` | List scheduled/unpublished posts |\n| `FACEBOOK_RESCHEDULE_POST` | Change scheduled publish time |\n| `FACEBOOK_UPDATE_POST` | Edit an existing post |\n| `FACEBOOK_PUBLISH_SCHEDULED_POST` | Publish a scheduled post immediately |\n| `FACEBOOK_UPLOAD_VIDEO` | Upload a video file to a Page |\n| `FACEBOOK_GET_PAGE_CONVERSATIONS` | List Messenger inbox conversations |\n| `FACEBOOK_GET_CONVERSATION_MESSAGES` | Retrieve messages from a conversation |\n| `FACEBOOK_SEND_MESSAGE` | Send a Messenger message from the Page |\n| `FACEBOOK_MARK_MESSAGE_SEEN` | Mark a message as seen |\n| `FACEBOOK_GET_PAGE_POSTS` | Retrieve posts from a Page feed |\n| `FACEBOOK_GET_USER_PAGES` | List Pages with tasks and tokens |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/faceup-automation/SKILL.md",
    "content": "---\nname: faceup-automation\ndescription: \"Automate Faceup tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Faceup Automation via Rube MCP\n\nAutomate Faceup operations through Composio's Faceup toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/faceup](https://composio.dev/toolkits/faceup)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Faceup connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `faceup`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `faceup`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Faceup operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Faceup task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"faceup\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Faceup-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `faceup` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/factorial-automation/SKILL.md",
    "content": "---\nname: factorial-automation\ndescription: \"Automate Factorial tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Factorial Automation via Rube MCP\n\nAutomate Factorial operations through Composio's Factorial toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/factorial](https://composio.dev/toolkits/factorial)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Factorial connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `factorial`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `factorial`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Factorial operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Factorial task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"factorial\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Factorial-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `factorial` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/feathery-automation/SKILL.md",
    "content": "---\nname: feathery-automation\ndescription: \"Automate Feathery tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Feathery Automation via Rube MCP\n\nAutomate Feathery operations through Composio's Feathery toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/feathery](https://composio.dev/toolkits/feathery)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Feathery connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `feathery`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `feathery`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Feathery operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Feathery task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"feathery\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Feathery-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `feathery` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/felt-automation/SKILL.md",
    "content": "---\nname: felt-automation\ndescription: \"Automate Felt tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Felt Automation via Rube MCP\n\nAutomate Felt operations through Composio's Felt toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/felt](https://composio.dev/toolkits/felt)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Felt connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `felt`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `felt`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Felt operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Felt task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"felt\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Felt-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `felt` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fibery-automation/SKILL.md",
    "content": "---\nname: fibery-automation\ndescription: \"Automate Fibery tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fibery Automation via Rube MCP\n\nAutomate Fibery operations through Composio's Fibery toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fibery](https://composio.dev/toolkits/fibery)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fibery connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fibery`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fibery`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fibery operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fibery task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fibery\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fibery-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fibery` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fidel-api-automation/SKILL.md",
    "content": "---\nname: fidel-api-automation\ndescription: \"Automate Fidel API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fidel API Automation via Rube MCP\n\nAutomate Fidel API operations through Composio's Fidel API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fidel_api](https://composio.dev/toolkits/fidel_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fidel API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fidel_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fidel_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fidel API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fidel API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fidel_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fidel API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fidel_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/files-com-automation/SKILL.md",
    "content": "---\nname: files-com-automation\ndescription: \"Automate Files Com tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Files Com Automation via Rube MCP\n\nAutomate Files Com operations through Composio's Files Com toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/files_com](https://composio.dev/toolkits/files_com)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Files Com connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `files_com`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `files_com`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Files Com operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Files Com task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"files_com\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Files Com-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `files_com` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fillout-forms-automation/SKILL.md",
    "content": "---\nname: fillout-forms-automation\ndescription: \"Automate Fillout tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fillout Automation via Rube MCP\n\nAutomate Fillout operations through Composio's Fillout toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fillout_forms](https://composio.dev/toolkits/fillout_forms)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fillout connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fillout operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fillout task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fillout_forms\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fillout-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fillout_forms-automation/SKILL.md",
    "content": "---\nname: fillout_forms-automation\ndescription: \"Automate Fillout tasks via Rube MCP (Composio): forms, submissions, workflows, and form builder. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fillout Automation via Rube MCP\n\nAutomate Fillout operations through Composio's Fillout toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fillout_forms](https://composio.dev/toolkits/fillout_forms)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fillout connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"forms, submissions, workflows, and form builder\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Fillout\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Fillout Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Fillout tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Fillout Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Fillout operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Fillout connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fillout-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fillout_forms` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/fillout_forms](https://composio.dev/toolkits/fillout_forms)\n"
  },
  {
    "path": "composio-skills/finage-automation/SKILL.md",
    "content": "---\nname: finage-automation\ndescription: \"Automate Finage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Finage Automation via Rube MCP\n\nAutomate Finage operations through Composio's Finage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/finage](https://composio.dev/toolkits/finage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Finage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `finage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `finage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Finage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Finage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"finage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Finage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `finage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/findymail-automation/SKILL.md",
    "content": "---\nname: findymail-automation\ndescription: \"Automate Findymail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Findymail Automation via Rube MCP\n\nAutomate Findymail operations through Composio's Findymail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/findymail](https://composio.dev/toolkits/findymail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Findymail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `findymail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `findymail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Findymail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Findymail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"findymail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Findymail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `findymail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/finerworks-automation/SKILL.md",
    "content": "---\nname: finerworks-automation\ndescription: \"Automate Finerworks tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Finerworks Automation via Rube MCP\n\nAutomate Finerworks operations through Composio's Finerworks toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/finerworks](https://composio.dev/toolkits/finerworks)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Finerworks connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `finerworks`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `finerworks`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Finerworks operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Finerworks task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"finerworks\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Finerworks-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `finerworks` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fingertip-automation/SKILL.md",
    "content": "---\nname: fingertip-automation\ndescription: \"Automate Fingertip tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fingertip Automation via Rube MCP\n\nAutomate Fingertip operations through Composio's Fingertip toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fingertip](https://composio.dev/toolkits/fingertip)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fingertip connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fingertip`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fingertip`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fingertip operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fingertip task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fingertip\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fingertip-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fingertip` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/finmei-automation/SKILL.md",
    "content": "---\nname: finmei-automation\ndescription: \"Automate Finmei tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Finmei Automation via Rube MCP\n\nAutomate Finmei operations through Composio's Finmei toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/finmei](https://composio.dev/toolkits/finmei)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Finmei connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `finmei`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `finmei`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Finmei operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Finmei task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"finmei\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Finmei-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `finmei` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fireberry-automation/SKILL.md",
    "content": "---\nname: fireberry-automation\ndescription: \"Automate Fireberry tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fireberry Automation via Rube MCP\n\nAutomate Fireberry operations through Composio's Fireberry toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fireberry](https://composio.dev/toolkits/fireberry)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fireberry connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fireberry`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fireberry`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fireberry operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fireberry task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fireberry\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fireberry-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fireberry` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/firecrawl-automation/SKILL.md",
    "content": "---\nname: Firecrawl Automation\ndescription: \"Automate web crawling and data extraction with Firecrawl -- scrape pages, crawl sites, extract structured data, batch scrape URLs, and map website structures through the Composio Firecrawl integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Firecrawl Automation\n\nRun **Firecrawl** web crawling and extraction directly from Claude Code. Scrape individual pages, crawl entire sites, extract structured data with AI, batch process URL lists, and map website structures without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/firecrawl](https://composio.dev/toolkits/firecrawl)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Firecrawl account when prompted. The agent will provide an authentication link.\n3. Be mindful of credit consumption -- scope your crawls tightly and test on small URL sets before scaling.\n\n---\n\n## Core Workflows\n\n### 1. Scrape a Single Page\n\nFetch content from a URL in multiple formats with optional browser actions for dynamic pages.\n\n**Tool:** `FIRECRAWL_SCRAPE`\n\nKey parameters:\n- `url` (required) -- fully qualified URL to scrape\n- `formats` -- output formats: `markdown` (default), `html`, `rawHtml`, `links`, `screenshot`, `json`\n- `onlyMainContent` (default true) -- extract main content only, excluding nav/footer/ads\n- `waitFor` -- milliseconds to wait for JS rendering (default 0)\n- `timeout` -- max wait in ms (default 30000)\n- `actions` -- browser actions before scraping (click, write, wait, press, scroll)\n- `includeTags` / `excludeTags` -- filter by HTML tags\n- `jsonOptions` -- for structured extraction with `schema` and/or `prompt`\n\nExample prompt: *\"Scrape the main content from https://example.com/pricing as markdown\"*\n\n---\n\n### 2. Crawl an Entire Site\n\nDiscover and scrape multiple pages from a website with configurable depth, path filters, and concurrency.\n\n**Tool:** `FIRECRAWL_CRAWL_V2`\n\nKey parameters:\n- `url` (required) -- starting URL for the crawl\n- `limit` (default 10) -- max pages to crawl\n- `maxDiscoveryDepth` -- depth limit from the root page\n- `includePaths` / `excludePaths` -- regex patterns for URL paths\n- `allowSubdomains` -- include subdomains (default false)\n- `crawlEntireDomain` -- follow sibling/parent links, not just children (default false)\n- `sitemap` -- `include` (default), `skip`, or `only`\n- `prompt` -- natural language to auto-configure crawler settings\n- `scrapeOptions_formats` -- output format for each page\n- `scrapeOptions_onlyMainContent` -- main content extraction per page\n\nExample prompt: *\"Crawl the docs section of firecrawl.dev, max 50 pages, only paths matching docs\"*\n\n---\n\n### 3. Extract Structured Data\n\nExtract structured JSON data from web pages using AI with a natural language prompt or JSON schema.\n\n**Tool:** `FIRECRAWL_EXTRACT`\n\nKey parameters:\n- `urls` (required) -- array of URLs to extract from (max 10 in beta). Supports wildcards like `https://example.com/blog/*`\n- `prompt` -- natural language description of what to extract\n- `schema` -- JSON Schema defining the desired output structure\n- `enable_web_search` -- allow crawling links outside initial domains (default false)\n\nAt least one of `prompt` or `schema` must be provided.\n\nCheck extraction status with `FIRECRAWL_EXTRACT_GET` using the returned job `id`.\n\nExample prompt: *\"Extract company name, pricing tiers, and feature lists from https://example.com/pricing\"*\n\n---\n\n### 4. Batch Scrape Multiple URLs\n\nScrape many URLs concurrently with shared configuration for efficient bulk data collection.\n\n**Tool:** `FIRECRAWL_BATCH_SCRAPE`\n\nKey parameters:\n- `urls` (required) -- array of URLs to scrape\n- `formats` -- output format for all pages (default `markdown`)\n- `onlyMainContent` (default true) -- main content extraction\n- `maxConcurrency` -- parallel scrape limit\n- `ignoreInvalidURLs` (default true) -- skip bad URLs instead of failing the batch\n- `location` -- geolocation settings with `country` code\n- `actions` -- browser actions applied to each page\n- `blockAds` (default true) -- block advertisements\n\nExample prompt: *\"Batch scrape these 20 product page URLs as markdown with ad blocking\"*\n\n---\n\n### 5. Map Website Structure\n\nDiscover all URLs on a website from a starting URL, useful for planning crawls or auditing site structure.\n\n**Tool:** `FIRECRAWL_MAP_MULTIPLE_URLS_BASED_ON_OPTIONS`\n\nKey parameters:\n- `url` (required) -- starting URL (must be `https://` or `http://`)\n- `search` -- guide URL discovery toward specific page types\n- `limit` (default 5000, max 100000) -- max URLs to return\n- `includeSubdomains` (default true) -- include subdomains\n- `ignoreQueryParameters` (default true) -- dedupe URLs differing only by query params\n- `sitemap` -- `include`, `skip`, or `only`\n\nExample prompt: *\"Map all URLs on docs.example.com, focusing on API reference pages\"*\n\n---\n\n### 6. Monitor and Manage Crawl Jobs\n\nTrack crawl progress, retrieve results, and cancel runaway jobs.\n\n**Tools:** `FIRECRAWL_CRAWL_GET`, `FIRECRAWL_GET_THE_STATUS_OF_A_CRAWL_JOB`, `FIRECRAWL_CANCEL_A_CRAWL_JOB`\n\n- `FIRECRAWL_CRAWL_GET` -- get status, progress, credits used, and crawled page data\n- `FIRECRAWL_CANCEL_A_CRAWL_JOB` -- stop an active or queued crawl\n\nBoth require the crawl job `id` (UUID) returned when the crawl was initiated.\n\nExample prompt: *\"Check the status of crawl job 019b0806-b7a1-7652-94c1-e865b5d2e89a\"*\n\n---\n\n## Known Pitfalls\n\n- **Rate limiting:** Firecrawl can trigger \"Rate limit exceeded\" errors (429). Prefer `FIRECRAWL_BATCH_SCRAPE` over many individual `FIRECRAWL_SCRAPE` calls, and implement backoff on 429/5xx responses.\n- **Credit consumption:** `FIRECRAWL_EXTRACT` can fail with \"Insufficient credits.\" Scope tightly and avoid broad homepage URLs that yield sparse fields. Test on small URL sets first.\n- **Nested error responses:** Per-page failures may be nested in `response.data.code` (e.g., `SCRAPE_DNS_RESOLUTION_ERROR`) even when the outer API call succeeds. Always validate inner status/error fields.\n- **JS-heavy pages:** Non-rendered fetches may miss key content. Use `waitFor` (e.g., 1000-5000ms) for dynamic pages, or configure `scrapeOptions_actions` to interact with the page before scraping.\n- **Extraction schema precision:** Vague or shifting schemas/prompts produce noisy, inconsistent output. Freeze your schema and test on a small sample before scaling to many URLs.\n- **Crawl jobs are async:** `FIRECRAWL_CRAWL_V2` returns immediately with a job ID. Use `FIRECRAWL_CRAWL_GET` to poll for results. Cancel stuck crawls with `FIRECRAWL_CANCEL_A_CRAWL_JOB` to avoid wasting credits.\n- **Extract job polling:** `FIRECRAWL_EXTRACT` is also async for larger jobs. Retrieve final output with `FIRECRAWL_EXTRACT_GET`.\n- **URL batching for extract:** Keep extract URL batches small (~10 URLs) to avoid 429 rate limit errors.\n- **Deeply nested responses:** Results are often nested under `data.data` or deeper. Inspect the returned shape rather than assuming flat keys.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `FIRECRAWL_SCRAPE` | Scrape a single URL with format/action options |\n| `FIRECRAWL_CRAWL_V2` | Crawl a website with depth/path control |\n| `FIRECRAWL_EXTRACT` | Extract structured data with AI prompt/schema |\n| `FIRECRAWL_BATCH_SCRAPE` | Batch scrape multiple URLs concurrently |\n| `FIRECRAWL_MAP_MULTIPLE_URLS_BASED_ON_OPTIONS` | Discover/map all URLs on a site |\n| `FIRECRAWL_CRAWL_GET` | Get crawl job status and results |\n| `FIRECRAWL_GET_THE_STATUS_OF_A_CRAWL_JOB` | Check crawl job progress |\n| `FIRECRAWL_CANCEL_A_CRAWL_JOB` | Cancel an active crawl job |\n| `FIRECRAWL_EXTRACT_GET` | Get extraction job status and results |\n| `FIRECRAWL_CRAWL_PARAMS_PREVIEW` | Preview crawl parameters before starting |\n| `FIRECRAWL_SEARCH` | Web search + scrape top results |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fireflies-automation/SKILL.md",
    "content": "---\nname: fireflies-automation\ndescription: \"Automate Fireflies tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fireflies Automation via Rube MCP\n\nAutomate Fireflies operations through Composio's Fireflies toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fireflies](https://composio.dev/toolkits/fireflies)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fireflies connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fireflies`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fireflies`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fireflies operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fireflies task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fireflies\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fireflies-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fireflies` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/firmao-automation/SKILL.md",
    "content": "---\nname: firmao-automation\ndescription: \"Automate Firmao tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Firmao Automation via Rube MCP\n\nAutomate Firmao operations through Composio's Firmao toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/firmao](https://composio.dev/toolkits/firmao)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Firmao connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `firmao`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `firmao`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Firmao operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Firmao task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"firmao\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Firmao-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `firmao` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fitbit-automation/SKILL.md",
    "content": "---\nname: fitbit-automation\ndescription: \"Automate Fitbit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fitbit Automation via Rube MCP\n\nAutomate Fitbit operations through Composio's Fitbit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fitbit](https://composio.dev/toolkits/fitbit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fitbit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fitbit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fitbit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fitbit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fitbit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fitbit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fitbit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fitbit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fixer-automation/SKILL.md",
    "content": "---\nname: fixer-automation\ndescription: \"Automate Fixer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fixer Automation via Rube MCP\n\nAutomate Fixer operations through Composio's Fixer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fixer](https://composio.dev/toolkits/fixer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fixer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fixer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fixer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fixer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fixer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fixer-io-automation/SKILL.md",
    "content": "---\nname: fixer-io-automation\ndescription: \"Automate Fixer IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fixer IO Automation via Rube MCP\n\nAutomate Fixer IO operations through Composio's Fixer IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fixer_io](https://composio.dev/toolkits/fixer_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fixer IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fixer IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fixer IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fixer_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fixer IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fixer_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/flexisign-automation/SKILL.md",
    "content": "---\nname: flexisign-automation\ndescription: \"Automate Flexisign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Flexisign Automation via Rube MCP\n\nAutomate Flexisign operations through Composio's Flexisign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/flexisign](https://composio.dev/toolkits/flexisign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Flexisign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `flexisign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `flexisign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Flexisign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Flexisign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"flexisign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Flexisign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `flexisign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/flowiseai-automation/SKILL.md",
    "content": "---\nname: flowiseai-automation\ndescription: \"Automate Flowiseai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Flowiseai Automation via Rube MCP\n\nAutomate Flowiseai operations through Composio's Flowiseai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/flowiseai](https://composio.dev/toolkits/flowiseai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Flowiseai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `flowiseai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `flowiseai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Flowiseai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Flowiseai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"flowiseai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Flowiseai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `flowiseai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/flutterwave-automation/SKILL.md",
    "content": "---\nname: flutterwave-automation\ndescription: \"Automate Flutterwave tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Flutterwave Automation via Rube MCP\n\nAutomate Flutterwave operations through Composio's Flutterwave toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/flutterwave](https://composio.dev/toolkits/flutterwave)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Flutterwave connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `flutterwave`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `flutterwave`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Flutterwave operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Flutterwave task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"flutterwave\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Flutterwave-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `flutterwave` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fluxguard-automation/SKILL.md",
    "content": "---\nname: fluxguard-automation\ndescription: \"Automate Fluxguard tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fluxguard Automation via Rube MCP\n\nAutomate Fluxguard operations through Composio's Fluxguard toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fluxguard](https://composio.dev/toolkits/fluxguard)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fluxguard connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fluxguard`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fluxguard`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fluxguard operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fluxguard task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fluxguard\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fluxguard-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fluxguard` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/folk-automation/SKILL.md",
    "content": "---\nname: folk-automation\ndescription: \"Automate Folk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Folk Automation via Rube MCP\n\nAutomate Folk operations through Composio's Folk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/folk](https://composio.dev/toolkits/folk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Folk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `folk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `folk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Folk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Folk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"folk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Folk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `folk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fomo-automation/SKILL.md",
    "content": "---\nname: fomo-automation\ndescription: \"Automate Fomo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fomo Automation via Rube MCP\n\nAutomate Fomo operations through Composio's Fomo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fomo](https://composio.dev/toolkits/fomo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fomo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fomo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fomo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fomo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fomo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fomo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fomo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fomo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/forcemanager-automation/SKILL.md",
    "content": "---\nname: forcemanager-automation\ndescription: \"Automate Forcemanager tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Forcemanager Automation via Rube MCP\n\nAutomate Forcemanager operations through Composio's Forcemanager toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/forcemanager](https://composio.dev/toolkits/forcemanager)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Forcemanager connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `forcemanager`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `forcemanager`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Forcemanager operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Forcemanager task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"forcemanager\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Forcemanager-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `forcemanager` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/formbricks-automation/SKILL.md",
    "content": "---\nname: formbricks-automation\ndescription: \"Automate Formbricks tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Formbricks Automation via Rube MCP\n\nAutomate Formbricks operations through Composio's Formbricks toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/formbricks](https://composio.dev/toolkits/formbricks)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Formbricks connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `formbricks`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `formbricks`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Formbricks operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Formbricks task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"formbricks\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Formbricks-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `formbricks` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/formcarry-automation/SKILL.md",
    "content": "---\nname: formcarry-automation\ndescription: \"Automate Formcarry tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Formcarry Automation via Rube MCP\n\nAutomate Formcarry operations through Composio's Formcarry toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/formcarry](https://composio.dev/toolkits/formcarry)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Formcarry connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `formcarry`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `formcarry`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Formcarry operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Formcarry task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"formcarry\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Formcarry-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `formcarry` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/formdesk-automation/SKILL.md",
    "content": "---\nname: formdesk-automation\ndescription: \"Automate Formdesk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Formdesk Automation via Rube MCP\n\nAutomate Formdesk operations through Composio's Formdesk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/formdesk](https://composio.dev/toolkits/formdesk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Formdesk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `formdesk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `formdesk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Formdesk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Formdesk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"formdesk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Formdesk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `formdesk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/formsite-automation/SKILL.md",
    "content": "---\nname: formsite-automation\ndescription: \"Automate Formsite tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Formsite Automation via Rube MCP\n\nAutomate Formsite operations through Composio's Formsite toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/formsite](https://composio.dev/toolkits/formsite)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Formsite connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `formsite`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `formsite`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Formsite operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Formsite task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"formsite\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Formsite-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `formsite` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/foursquare-automation/SKILL.md",
    "content": "---\nname: foursquare-automation\ndescription: \"Automate Foursquare tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Foursquare Automation via Rube MCP\n\nAutomate Foursquare operations through Composio's Foursquare toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/foursquare](https://composio.dev/toolkits/foursquare)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Foursquare connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `foursquare`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `foursquare`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Foursquare operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Foursquare task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"foursquare\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Foursquare-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `foursquare` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fraudlabs-pro-automation/SKILL.md",
    "content": "---\nname: fraudlabs-pro-automation\ndescription: \"Automate Fraudlabs Pro tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fraudlabs Pro Automation via Rube MCP\n\nAutomate Fraudlabs Pro operations through Composio's Fraudlabs Pro toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fraudlabs_pro](https://composio.dev/toolkits/fraudlabs_pro)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fraudlabs Pro connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fraudlabs_pro`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fraudlabs_pro`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fraudlabs Pro operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fraudlabs Pro task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fraudlabs_pro\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fraudlabs Pro-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fraudlabs_pro` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/freshbooks-automation/SKILL.md",
    "content": "---\nname: FreshBooks Automation\ndescription: \"FreshBooks Automation: manage businesses, projects, time tracking, and billing in FreshBooks cloud accounting\"\nrequires:\n  mcp: [rube]\n---\n\n# FreshBooks Automation\n\nAutomate FreshBooks operations including listing businesses, managing projects, tracking time, and monitoring budgets for small and medium-sized business accounting.\n\n**Toolkit docs:** [composio.dev/toolkits/freshbooks](https://composio.dev/toolkits/freshbooks)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `freshbooks` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. List Businesses\n\nRetrieve all businesses associated with the authenticated user. The `business_id` from this response is required for most other FreshBooks API calls.\n\n**Tool:** `FRESHBOOKS_LIST_BUSINESSES`\n\n**Parameters:** None required.\n\n**Example:**\n```\nTool: FRESHBOOKS_LIST_BUSINESSES\nArguments: {}\n```\n\n**Output:** Returns business membership information including all businesses the user has access to, along with their role in each business.\n\n> **Important:** Always call this first to obtain a valid `business_id` before performing project-specific operations.\n\n---\n\n### 2. List and Filter Projects\n\nRetrieve all projects for a business with comprehensive filtering and sorting options.\n\n**Tool:** `FRESHBOOKS_LIST_PROJECTS`\n\n**Key Parameters:**\n- `business_id` (required) -- Business ID obtained from `FRESHBOOKS_LIST_BUSINESSES`\n- `active` -- Filter by active status: `true` (active only), `false` (inactive only), omit for all\n- `complete` -- Filter by completion: `true` (completed), `false` (incomplete), omit for all\n- `sort_by` -- Sort order: `\"created_at\"`, `\"due_date\"`, or `\"title\"`\n- `updated_since` -- UTC datetime in RFC3339 format, e.g., `\"2026-01-01T00:00:00Z\"`\n- `include_logged_duration` -- `true` to include total logged time (in seconds) per project\n- `skip_group` -- `true` to omit team member/invitation data (reduces response size)\n\n**Example:**\n```\nTool: FRESHBOOKS_LIST_PROJECTS\nArguments:\n  business_id: 123456\n  active: true\n  complete: false\n  sort_by: \"due_date\"\n  include_logged_duration: true\n```\n\n**Use Cases:**\n- Get all projects for time tracking or invoicing\n- Find projects by client, status, or date range\n- Monitor project completion and budget tracking\n- Retrieve team assignments and project groups\n\n---\n\n### 3. Monitor Active Projects\n\nTrack project progress and budgets by filtering for active, incomplete projects.\n\n**Steps:**\n1. Call `FRESHBOOKS_LIST_BUSINESSES` to get `business_id`\n2. Call `FRESHBOOKS_LIST_PROJECTS` with `active: true`, `complete: false`, `include_logged_duration: true`\n3. Analyze logged duration vs. budget for each project\n\n---\n\n### 4. Review Recently Updated Projects\n\nCheck for recent project activity using the `updated_since` filter.\n\n**Steps:**\n1. Call `FRESHBOOKS_LIST_BUSINESSES` to get `business_id`\n2. Call `FRESHBOOKS_LIST_PROJECTS` with `updated_since` set to your cutoff datetime\n3. Review returned projects for recent changes\n\n**Example:**\n```\nTool: FRESHBOOKS_LIST_PROJECTS\nArguments:\n  business_id: 123456\n  updated_since: \"2026-02-01T00:00:00Z\"\n  sort_by: \"created_at\"\n```\n\n---\n\n## Recommended Execution Plan\n\n1. **Get the business ID** by calling `FRESHBOOKS_LIST_BUSINESSES`\n2. **List projects** using `FRESHBOOKS_LIST_PROJECTS` with the obtained `business_id`\n3. **Filter as needed** using `active`, `complete`, `updated_since`, and `sort_by` parameters\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **business_id required** | Most FreshBooks operations require a `business_id`. Always call `FRESHBOOKS_LIST_BUSINESSES` first to obtain it. |\n| **Date format** | The `updated_since` parameter must be in RFC3339 format: `\"2026-01-01T00:00:00Z\"`. Other formats will fail. |\n| **Paginated results** | Project list responses are paginated. Check for additional pages in the response. |\n| **Empty results** | Returns an empty list if no projects exist or match the applied filters. This is not an error. |\n| **Logged duration units** | When `include_logged_duration` is true, the duration is returned in seconds. Convert to hours (divide by 3600) for display. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `FRESHBOOKS_LIST_BUSINESSES` | List all businesses for the authenticated user |\n| `FRESHBOOKS_LIST_PROJECTS` | List projects with filtering and sorting for a business |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/front-automation/SKILL.md",
    "content": "---\nname: front-automation\ndescription: \"Automate Front tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Front Automation via Rube MCP\n\nAutomate Front operations through Composio's Front toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/front](https://composio.dev/toolkits/front)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Front connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `front`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `front`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Front operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Front task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"front\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Front-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `front` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/fullenrich-automation/SKILL.md",
    "content": "---\nname: fullenrich-automation\ndescription: \"Automate Fullenrich tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Fullenrich Automation via Rube MCP\n\nAutomate Fullenrich operations through Composio's Fullenrich toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/fullenrich](https://composio.dev/toolkits/fullenrich)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Fullenrich connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `fullenrich`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `fullenrich`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Fullenrich operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Fullenrich task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"fullenrich\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Fullenrich-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `fullenrich` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gagelist-automation/SKILL.md",
    "content": "---\nname: gagelist-automation\ndescription: \"Automate Gagelist tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gagelist Automation via Rube MCP\n\nAutomate Gagelist operations through Composio's Gagelist toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gagelist](https://composio.dev/toolkits/gagelist)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gagelist connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gagelist`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gagelist`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gagelist operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gagelist task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gagelist\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gagelist-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gagelist` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gamma-automation/SKILL.md",
    "content": "---\nname: gamma-automation\ndescription: \"Automate Gamma tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gamma Automation via Rube MCP\n\nAutomate Gamma operations through Composio's Gamma toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gamma](https://composio.dev/toolkits/gamma)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gamma connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gamma`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gamma`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gamma operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gamma task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gamma\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gamma-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gamma` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gan-ai-automation/SKILL.md",
    "content": "---\nname: gan-ai-automation\ndescription: \"Automate Gan AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gan AI Automation via Rube MCP\n\nAutomate Gan AI operations through Composio's Gan AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gan_ai](https://composio.dev/toolkits/gan_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gan AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gan_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gan_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gan AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gan AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gan_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gan AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gan_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gatherup-automation/SKILL.md",
    "content": "---\nname: gatherup-automation\ndescription: \"Automate Gatherup tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gatherup Automation via Rube MCP\n\nAutomate Gatherup operations through Composio's Gatherup toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gatherup](https://composio.dev/toolkits/gatherup)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gatherup connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gatherup`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gatherup`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gatherup operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gatherup task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gatherup\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gatherup-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gatherup` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gemini-automation/SKILL.md",
    "content": "---\nname: gemini-automation\ndescription: \"Automate Gemini tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gemini Automation via Rube MCP\n\nAutomate Gemini operations through Composio's Gemini toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gemini](https://composio.dev/toolkits/gemini)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gemini connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gemini`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gemini`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gemini operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gemini task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gemini\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gemini-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gemini` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gender-api-automation/SKILL.md",
    "content": "---\nname: gender-api-automation\ndescription: \"Automate Gender API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gender API Automation via Rube MCP\n\nAutomate Gender API operations through Composio's Gender API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gender_api](https://composio.dev/toolkits/gender_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gender API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gender_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gender_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gender API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gender API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gender_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gender API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gender_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/genderapi-io-automation/SKILL.md",
    "content": "---\nname: genderapi-io-automation\ndescription: \"Automate Genderapi IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Genderapi IO Automation via Rube MCP\n\nAutomate Genderapi IO operations through Composio's Genderapi IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/genderapi_io](https://composio.dev/toolkits/genderapi_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Genderapi IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `genderapi_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `genderapi_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Genderapi IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Genderapi IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"genderapi_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Genderapi IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `genderapi_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/genderize-automation/SKILL.md",
    "content": "---\nname: genderize-automation\ndescription: \"Automate Genderize tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Genderize Automation via Rube MCP\n\nAutomate Genderize operations through Composio's Genderize toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/genderize](https://composio.dev/toolkits/genderize)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Genderize connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `genderize`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `genderize`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Genderize operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Genderize task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"genderize\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Genderize-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `genderize` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/geoapify-automation/SKILL.md",
    "content": "---\nname: geoapify-automation\ndescription: \"Automate Geoapify tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Geoapify Automation via Rube MCP\n\nAutomate Geoapify operations through Composio's Geoapify toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/geoapify](https://composio.dev/toolkits/geoapify)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Geoapify connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `geoapify`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `geoapify`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Geoapify operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Geoapify task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"geoapify\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Geoapify-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `geoapify` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/geocodio-automation/SKILL.md",
    "content": "---\nname: geocodio-automation\ndescription: \"Automate Geocodio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Geocodio Automation via Rube MCP\n\nAutomate Geocodio operations through Composio's Geocodio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/geocodio](https://composio.dev/toolkits/geocodio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Geocodio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `geocodio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `geocodio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Geocodio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Geocodio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"geocodio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Geocodio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `geocodio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/geokeo-automation/SKILL.md",
    "content": "---\nname: geokeo-automation\ndescription: \"Automate Geokeo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Geokeo Automation via Rube MCP\n\nAutomate Geokeo operations through Composio's Geokeo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/geokeo](https://composio.dev/toolkits/geokeo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Geokeo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `geokeo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `geokeo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Geokeo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Geokeo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"geokeo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Geokeo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `geokeo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/getform-automation/SKILL.md",
    "content": "---\nname: getform-automation\ndescription: \"Automate Getform tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Getform Automation via Rube MCP\n\nAutomate Getform operations through Composio's Getform toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/getform](https://composio.dev/toolkits/getform)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Getform connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `getform`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `getform`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Getform operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Getform task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"getform\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Getform-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `getform` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gift-up-automation/SKILL.md",
    "content": "---\nname: gift-up-automation\ndescription: \"Automate Gift Up tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gift Up Automation via Rube MCP\n\nAutomate Gift Up operations through Composio's Gift Up toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gift_up](https://composio.dev/toolkits/gift_up)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gift Up connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gift_up`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gift_up`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gift Up operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gift Up task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gift_up\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gift Up-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gift_up` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gigasheet-automation/SKILL.md",
    "content": "---\nname: gigasheet-automation\ndescription: \"Automate Gigasheet tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gigasheet Automation via Rube MCP\n\nAutomate Gigasheet operations through Composio's Gigasheet toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gigasheet](https://composio.dev/toolkits/gigasheet)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gigasheet connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gigasheet`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gigasheet`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gigasheet operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gigasheet task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gigasheet\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gigasheet-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gigasheet` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/giphy-automation/SKILL.md",
    "content": "---\nname: giphy-automation\ndescription: \"Automate Giphy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Giphy Automation via Rube MCP\n\nAutomate Giphy operations through Composio's Giphy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/giphy](https://composio.dev/toolkits/giphy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Giphy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `giphy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `giphy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Giphy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Giphy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"giphy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Giphy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `giphy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gist-automation/SKILL.md",
    "content": "---\nname: gist-automation\ndescription: \"Automate Gist tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gist Automation via Rube MCP\n\nAutomate Gist operations through Composio's Gist toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gist](https://composio.dev/toolkits/gist)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gist connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gist`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gist`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gist operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gist task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gist\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gist-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gist` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/givebutter-automation/SKILL.md",
    "content": "---\nname: givebutter-automation\ndescription: \"Automate Givebutter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Givebutter Automation via Rube MCP\n\nAutomate Givebutter operations through Composio's Givebutter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/givebutter](https://composio.dev/toolkits/givebutter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Givebutter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `givebutter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `givebutter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Givebutter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Givebutter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"givebutter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Givebutter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `givebutter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gladia-automation/SKILL.md",
    "content": "---\nname: gladia-automation\ndescription: \"Automate Gladia tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gladia Automation via Rube MCP\n\nAutomate Gladia operations through Composio's Gladia toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gladia](https://composio.dev/toolkits/gladia)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gladia connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gladia`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gladia`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gladia operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gladia task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gladia\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gladia-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gladia` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gleap-automation/SKILL.md",
    "content": "---\nname: gleap-automation\ndescription: \"Automate Gleap tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gleap Automation via Rube MCP\n\nAutomate Gleap operations through Composio's Gleap toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gleap](https://composio.dev/toolkits/gleap)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gleap connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gleap`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gleap`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gleap operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gleap task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gleap\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gleap-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gleap` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/globalping-automation/SKILL.md",
    "content": "---\nname: globalping-automation\ndescription: \"Automate Globalping tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Globalping Automation via Rube MCP\n\nAutomate Globalping operations through Composio's Globalping toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/globalping](https://composio.dev/toolkits/globalping)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Globalping connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `globalping`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `globalping`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Globalping operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Globalping task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"globalping\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Globalping-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `globalping` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/go-to-webinar-automation/SKILL.md",
    "content": "---\nname: go-to-webinar-automation\ndescription: \"Automate GoToWebinar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# GoToWebinar Automation via Rube MCP\n\nAutomate GoToWebinar operations through Composio's GoToWebinar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/go_to_webinar](https://composio.dev/toolkits/go_to_webinar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active GoToWebinar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `go_to_webinar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `go_to_webinar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"GoToWebinar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific GoToWebinar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"go_to_webinar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with GoToWebinar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `go_to_webinar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/godial-automation/SKILL.md",
    "content": "---\nname: godial-automation\ndescription: \"Automate Godial tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Godial Automation via Rube MCP\n\nAutomate Godial operations through Composio's Godial toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/godial](https://composio.dev/toolkits/godial)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Godial connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `godial`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `godial`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Godial operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Godial task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"godial\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Godial-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `godial` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gong-automation/SKILL.md",
    "content": "---\nname: Gong Automation\ndescription: \"Automate Gong conversation intelligence -- retrieve call recordings, transcripts, detailed analytics, speaker stats, and workspace data -- using natural language through the Composio MCP integration.\"\ncategory: conversation-intelligence\nrequires:\n  mcp:\n    - rube\n---\n\n# Gong Automation\n\nUnlock insights from your sales calls -- retrieve transcripts, analyze call data by date range, access detailed conversation analytics with topics and trackers, and manage workspaces -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/gong](https://composio.dev/toolkits/gong)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Gong account when prompted (OAuth / Bearer token authentication).\n3. Start issuing natural language commands to analyze your call data.\n\n---\n\n## Core Workflows\n\n### 1. Retrieve Call Transcripts by Date Range\nGet transcripts for all calls within a specified time period, with optional filtering by specific call IDs or workspace.\n\n**Tool:** `GONG_RETRIEVE_TRANSCRIPTS_OF_CALLS_V2_CALLS_TRANSCRIPT`\n\n**Example prompt:**\n> \"Get Gong transcripts for all calls from February 1-10, 2025\"\n\n**Key parameters:**\n- `filter__fromDateTime` -- ISO-8601 start date (e.g., `2025-02-01T00:00:00Z`)\n- `filter__toDateTime` -- ISO-8601 end date (e.g., `2025-02-10T23:59:59Z`)\n- `filter__callIds` -- Optional array of specific call IDs to filter\n- `filter__workspaceId` -- Optional workspace ID filter\n- `cursor` -- Pagination cursor from previous response\n\n**Required scope:** `api:calls:read:transcript`\n\n---\n\n### 2. Get Transcript for Specific Calls\nRetrieve transcripts with speaker information, timestamps, and topic categorization using a filter object.\n\n**Tool:** `GONG_GET_CALL_TRANSCRIPT`\n\n**Example prompt:**\n> \"Get the Gong transcript for call ID 555785916001072125\"\n\n**Key parameters (filter required):**\n- `filter.callIds` -- Array of specific call IDs (e.g., `[\"555785916001072125\"]`)\n- `filter.fromDateTime` -- ISO-8601 start date\n- `filter.toDateTime` -- ISO-8601 end date\n- `filter.workspaceId` -- Optional workspace filter\n- `cursor` -- Pagination cursor\n\n---\n\n### 3. List Calls by Date Range\nRetrieve basic call metadata (participants, duration, timing) for calls within a date range.\n\n**Tool:** `GONG_RETRIEVE_CALL_DATA_BY_DATE_RANGE_V2_CALLS`\n\n**Example prompt:**\n> \"List all Gong calls from last week\"\n\n**Key parameters (both required):**\n- `fromDateTime` -- ISO-8601 start date (e.g., `2025-02-03T00:00:00Z`)\n- `toDateTime` -- ISO-8601 end date (e.g., `2025-02-10T00:00:00Z`)\n- `workspaceId` -- Optional workspace filter\n- `cursor` -- Pagination cursor\n\n**Required scope:** `api:calls:read:basic`\n\n---\n\n### 4. Get Detailed Call Analytics\nRetrieve extensive call details including highlights, key points, topics, trackers, speaker stats, questions, and media URLs.\n\n**Tool:** `GONG_RETRIEVE_FILTERED_CALL_DETAILS`\n\n**Example prompt:**\n> \"Get detailed analytics for Gong calls this week including topics, key points, and speaker stats\"\n\n**Key parameters:**\n- `filter__fromDateTime` / `filter__toDateTime` -- Date range filter\n- `filter__callIds` -- Specific call IDs\n- `filter__primaryUserIds` -- Filter by call host user IDs\n- Content selectors (all boolean):\n  - `contentSelector__exposedFields__content__keyPoints` -- Key points of the call\n  - `contentSelector__exposedFields__content__topics` -- Topic durations\n  - `contentSelector__exposedFields__content__highlights` -- Call highlights\n  - `contentSelector__exposedFields__content__outline` -- Call outline\n  - `contentSelector__exposedFields__content__brief` -- Spotlight call brief\n  - `contentSelector__exposedFields__content__callOutcome` -- Call outcome\n  - `contentSelector__exposedFields__content__trackers` -- Smart/keyword trackers\n  - `contentSelector__exposedFields__content__trackerOccurrences` -- Tracker timing and speaker (requires trackers=true)\n  - `contentSelector__exposedFields__interaction__speakers` -- Time each participant spoke\n  - `contentSelector__exposedFields__interaction__questions` -- Question counts\n  - `contentSelector__exposedFields__interaction__personInteractionStats` -- Host statistics\n  - `contentSelector__exposedFields__media` -- Audio/video URLs (valid 8 hours)\n  - `contentSelector__exposedFields__parties` -- Party information\n  - `contentSelector__exposedFields__collaboration__publicComments` -- Public comments\n- `contentSelector__context` -- \"Basic\", \"Extended\", or \"None\" for CRM/external system links\n\n**Required scope:** `api:calls:read:extensive` (plus `api:calls:read:media-url` for media)\n\n---\n\n### 5. Get a Specific Call by ID\nRetrieve basic data for a single call using its unique Gong ID.\n\n**Tool:** `GONG_RETRIEVE_DATA_FOR_A_SPECIFIC_CALL_V2_CALLS_ID`\n\n**Example prompt:**\n> \"Get details for Gong call 1223781272986876929\"\n\n**Key parameters (required):**\n- `id` -- Gong's unique numeric identifier for the call (up to 20 digits)\n\n**Required scope:** `api:calls:read:basic`\n\n---\n\n### 6. List Company Workspaces\nRetrieve all workspaces in your Gong organization to get workspace IDs for filtering.\n\n**Tool:** `GONG_LIST_ALL_COMPANY_WORKSPACES_V2_WORKSPACES`\n\n**Example prompt:**\n> \"List all Gong workspaces in my company\"\n\n**Key parameters:** None required.\n\n**Required scope:** `api:workspaces:read`\n\n---\n\n## Known Pitfalls\n\n- **ISO-8601 date format is mandatory**: All date parameters must use ISO-8601 format with timezone: `2025-02-01T00:00:00Z` or `2025-02-01T02:30:00-07:00`. Plain dates will fail.\n- **Date range is exclusive on toDateTime**: The `toDateTime` parameter returns calls started UP TO BUT EXCLUDING the specified time. To include calls on a specific day, set `toDateTime` to the next day.\n- **Pagination is required for large result sets**: All list endpoints return paginated results. Use the `cursor` value from the previous response to fetch the next page. Continue until no cursor is returned.\n- **Scope requirements vary by endpoint**: Different endpoints require different API scopes. Transcript access needs `api:calls:read:transcript`, basic call data needs `api:calls:read:basic`, and detailed analytics need `api:calls:read:extensive`.\n- **Media URLs expire after 8 hours**: Audio and video URLs returned by the detailed call endpoint are temporary and expire after 8 hours.\n- **Tracker occurrence data availability**: Tracker occurrence data (timing and speaker ID) is only available for calls recorded since January 1, 2023. Contact Gong support for backfill.\n- **Web-conference vs. regular calls**: For web-conference calls recorded by Gong, the date represents the scheduled time. For other calls, it represents the actual start time.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| Get transcripts by date | `GONG_RETRIEVE_TRANSCRIPTS_OF_CALLS_V2_CALLS_TRANSCRIPT` | None (date range recommended) |\n| Get call transcript | `GONG_GET_CALL_TRANSCRIPT` | `filter` object |\n| List calls by date | `GONG_RETRIEVE_CALL_DATA_BY_DATE_RANGE_V2_CALLS` | `fromDateTime`, `toDateTime` |\n| Get detailed call analytics | `GONG_RETRIEVE_FILTERED_CALL_DETAILS` | None (date range or call IDs recommended) |\n| Get specific call | `GONG_RETRIEVE_DATA_FOR_A_SPECIFIC_CALL_V2_CALLS_ID` | `id` |\n| List workspaces | `GONG_LIST_ALL_COMPANY_WORKSPACES_V2_WORKSPACES` | None |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/goodbits-automation/SKILL.md",
    "content": "---\nname: goodbits-automation\ndescription: \"Automate Goodbits tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Goodbits Automation via Rube MCP\n\nAutomate Goodbits operations through Composio's Goodbits toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/goodbits](https://composio.dev/toolkits/goodbits)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Goodbits connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `goodbits`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `goodbits`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Goodbits operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Goodbits task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"goodbits\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Goodbits-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `goodbits` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/goody-automation/SKILL.md",
    "content": "---\nname: goody-automation\ndescription: \"Automate Goody tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Goody Automation via Rube MCP\n\nAutomate Goody operations through Composio's Goody toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/goody](https://composio.dev/toolkits/goody)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Goody connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `goody`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `goody`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Goody operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Goody task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"goody\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Goody-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `goody` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-address-validation-automation/SKILL.md",
    "content": "---\nname: google-address-validation-automation\ndescription: \"Automate Google Address Validation tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Address Validation Automation via Rube MCP\n\nAutomate Google Address Validation operations through Composio's Google Address Validation toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_address_validation](https://composio.dev/toolkits/google_address_validation)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Address Validation connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_address_validation`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_address_validation`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Address Validation operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Address Validation task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"google_address_validation\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Address Validation-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_address_validation` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-admin-automation/SKILL.md",
    "content": "---\nname: google-admin-automation\ndescription: \"Automate Google Workspace Admin tasks via Rube MCP (Composio): manage users, groups, memberships, suspend accounts, create users, add aliases. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Workspace Admin Automation via Rube MCP\n\nManage Google Workspace users, groups, memberships, and organizational settings programmatically using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/google_admin](https://composio.dev/toolkits/google_admin)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_admin`\n- Google Workspace admin privileges for the authenticated account\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_admin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. List All Users\nUse `GOOGLE_ADMIN_LIST_USERS` to retrieve Google Workspace users with optional filtering and pagination.\n```\nTool: GOOGLE_ADMIN_LIST_USERS\nParameters:\n  - customer: Customer ID or \"my_customer\" (default)\n  - domain: Domain to list users from\n  - query: Filter string (e.g., \"orgName=Engineering\", \"isSuspended=false\")\n  - max_results: Maximum results (1-500, default 100)\n  - order_by: Sort by \"email\", \"givenName\", or \"familyName\"\n  - sort_order: \"ASCENDING\" or \"DESCENDING\"\n  - page_token: Pagination token\n```\n\n### 2. Create a New User\nUse `GOOGLE_ADMIN_CREATE_USER` to provision a new Google Workspace account.\n```\nTool: GOOGLE_ADMIN_CREATE_USER\nParameters:\n  - primary_email (required): User's email (e.g., \"john.doe@company.com\")\n  - given_name (required): First name\n  - family_name (required): Last name\n  - password (required): Password meeting domain requirements\n  - org_unit_path: Organizational unit (default: \"/\")\n  - change_password_at_next_login: Force password change (default: true)\n  - recovery_email: Recovery email address\n  - recovery_phone: Recovery phone number\n  - suspended: Whether account starts suspended (default: false)\n```\n\n### 3. List and Manage Groups\nUse `GOOGLE_ADMIN_LIST_GROUPS` to list groups, and `GOOGLE_ADMIN_CREATE_GROUP` to create new ones.\n```\nTool: GOOGLE_ADMIN_LIST_GROUPS\nParameters:\n  - customer: \"my_customer\" (default)\n  - domain: Filter by domain\n  - query: Filter (e.g., \"name=Engineering*\")\n  - max_results: Max results (1-200)\n  - order_by: Sort by \"email\"\n  - page_token: Pagination token\n\nTool: GOOGLE_ADMIN_CREATE_GROUP\nParameters:\n  - email (required): Group email address (e.g., \"engineering@company.com\")\n  - name (required): Display name (e.g., \"Engineering Team\")\n  - description: Group purpose description\n```\n\n### 4. Add Users to Groups\nUse `GOOGLE_ADMIN_ADD_USER_TO_GROUP` to manage group membership.\n```\nTool: GOOGLE_ADMIN_ADD_USER_TO_GROUP\nParameters:\n  - group_key (required): Group email or ID\n  - user_key (required): User email or ID to add\n  - role: \"MEMBER\" (default), \"MANAGER\", or \"OWNER\"\n```\n\n### 5. Suspend or Unsuspend Users\nUse `GOOGLE_ADMIN_SUSPEND_USER` to toggle user account suspension.\n```\nTool: GOOGLE_ADMIN_SUSPEND_USER\nParameters:\n  - user_key (required): User's email or unique ID\n  - suspended: true to suspend, false to unsuspend (default: true)\n  - suspension_reason: Reason for suspension (optional)\n```\n\n### 6. Get User or Group Details\nUse `GOOGLE_ADMIN_GET_USER` or `GOOGLE_ADMIN_GET_GROUP` to retrieve detailed information.\n```\nTool: GOOGLE_ADMIN_GET_USER\nParameters:\n  - user_key (required): User's email or unique ID\n\nTool: GOOGLE_ADMIN_GET_GROUP\nParameters:\n  - group_key (required): Group's email or unique ID\n```\n\n## Common Patterns\n\n- **Onboarding workflow**: Use `GOOGLE_ADMIN_CREATE_USER` to provision the account, then `GOOGLE_ADMIN_ADD_USER_TO_GROUP` to add them to relevant groups.\n- **Offboarding workflow**: Use `GOOGLE_ADMIN_SUSPEND_USER` to disable access, or `GOOGLE_ADMIN_DELETE_USER` for permanent removal.\n- **Audit group membership**: Use `GOOGLE_ADMIN_LIST_GROUPS` to find groups, then `GOOGLE_ADMIN_LIST_GROUP_MEMBERS` to review members.\n- **Bulk user management**: List users with `GOOGLE_ADMIN_LIST_USERS` and filter queries, then iterate for updates.\n- **Add email aliases**: Use `GOOGLE_ADMIN_ADD_USER_ALIAS` to add alternative email addresses for a user.\n- **Look up user details**: Use `GOOGLE_ADMIN_GET_USER` to retrieve full profile information before making changes.\n\n## Known Pitfalls\n\n- **Admin privileges required**: All tools require the authenticated user to have Google Workspace administrator privileges. Non-admin accounts will receive permission errors.\n- **Delete is permanent**: `GOOGLE_ADMIN_DELETE_USER` permanently removes a user account. This action cannot be undone.\n- **user_key accepts email or ID**: The `user_key` parameter accepts both the user's primary email address and their unique numeric user ID.\n- **Group membership replaces**: When adding to groups, the `role` parameter controls the member's role. There is no \"update role\" -- remove and re-add to change roles.\n- **Customer ID**: Use `\"my_customer\"` as the `customer` parameter for the authenticated user's organization. Specific customer IDs look like `C01abc123`.\n- **Pagination**: Both user and group list endpoints may return paginated results. Always check for `page_token` in responses for complete results.\n- **Password requirements**: `GOOGLE_ADMIN_CREATE_USER` requires a password that meets the domain's password policy. Weak passwords will be rejected.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| List users | `GOOGLE_ADMIN_LIST_USERS` | `customer`, `domain`, `query`, `max_results` |\n| Get user details | `GOOGLE_ADMIN_GET_USER` | `user_key` |\n| Create user | `GOOGLE_ADMIN_CREATE_USER` | `primary_email`, `given_name`, `family_name`, `password` |\n| Delete user | `GOOGLE_ADMIN_DELETE_USER` | `user_key` |\n| Suspend user | `GOOGLE_ADMIN_SUSPEND_USER` | `user_key`, `suspended` |\n| Add user alias | `GOOGLE_ADMIN_ADD_USER_ALIAS` | (see full schema via RUBE_SEARCH_TOOLS) |\n| List groups | `GOOGLE_ADMIN_LIST_GROUPS` | `customer`, `domain`, `query` |\n| Get group details | `GOOGLE_ADMIN_GET_GROUP` | `group_key` |\n| Create group | `GOOGLE_ADMIN_CREATE_GROUP` | `email`, `name`, `description` |\n| Add to group | `GOOGLE_ADMIN_ADD_USER_TO_GROUP` | `group_key`, `user_key`, `role` |\n| List group members | `GOOGLE_ADMIN_LIST_GROUP_MEMBERS` | (see full schema via RUBE_SEARCH_TOOLS) |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-classroom-automation/SKILL.md",
    "content": "---\nname: google-classroom-automation\ndescription: \"Automate Google Classroom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Classroom Automation via Rube MCP\n\nAutomate Google Classroom operations through Composio's Google Classroom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_classroom](https://composio.dev/toolkits/google_classroom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Classroom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Classroom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Classroom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"google_classroom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Classroom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-cloud-vision-automation/SKILL.md",
    "content": "---\nname: google-cloud-vision-automation\ndescription: \"Automate Google Cloud Vision tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Cloud Vision Automation via Rube MCP\n\nAutomate Google Cloud Vision operations through Composio's Google Cloud Vision toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_cloud_vision](https://composio.dev/toolkits/google_cloud_vision)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Cloud Vision connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_cloud_vision`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_cloud_vision`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Cloud Vision operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Cloud Vision task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"google_cloud_vision\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Cloud Vision-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_cloud_vision` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-maps-automation/SKILL.md",
    "content": "---\nname: google-maps-automation\ndescription: \"Automate Google Maps tasks via Rube MCP (Composio): geocode addresses, search places, get directions, compute route matrices, reverse geocode, autocomplete, get place details. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Maps Automation via Rube MCP\n\nGeocode addresses, search places, get directions, compute distance matrices, and retrieve place details using Google Maps via Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/google_maps](https://composio.dev/toolkits/google_maps)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_maps`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_maps`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. Geocode an Address\nUse `GOOGLE_MAPS_GEOCODING_API` to convert a street address into geographic coordinates (latitude/longitude).\n```\nTool: GOOGLE_MAPS_GEOCODING_API\nParameters:\n  - address: Street address or plus code to geocode\n  - latlng: Lat/lng for reverse geocoding (e.g., \"40.714224,-73.961452\")\n  - place_id: Place ID for place geocoding\n  - language: Language for results\n  - region: Region bias (ccTLD code)\n  - bounds: Bounding box for viewport bias\n  - components: Component filter (e.g., \"postal_code:94043|country:US\")\n```\n\n### 2. Search for Places\nUse `GOOGLE_MAPS_TEXT_SEARCH` to find places using a free-text query.\n```\nTool: GOOGLE_MAPS_TEXT_SEARCH\nParameters:\n  - textQuery (required): Search text (e.g., \"restaurants in London\")\n  - fieldMask: Fields to return (e.g., \"displayName,formattedAddress,rating\")\n  - maxResultCount: Max results (1-20, default 10)\n```\n\n### 3. Get Directions Between Two Locations\nUse `GOOGLE_MAPS_GET_ROUTE` to calculate routes with distance and duration.\n```\nTool: GOOGLE_MAPS_GET_ROUTE\nParameters:\n  - origin_address (required): Starting point (address or \"lat,lng\")\n  - destination_address (required): End point (address or \"lat,lng\")\n  - travelMode: DRIVE, BICYCLE, WALK, TWO_WHEELER, or TRANSIT\n  - routingPreference: TRAFFIC_UNAWARE, TRAFFIC_AWARE, TRAFFIC_AWARE_OPTIMAL\n  - computeAlternativeRoutes: Return alternative routes (boolean)\n  - units: METRIC or IMPERIAL\n  - languageCode: BCP-47 language code\n  - routeModifiers_avoidTolls / avoidHighways / avoidFerries: Route preferences\n```\n\n### 4. Compute Distance Matrix\nUse `GOOGLE_MAPS_COMPUTE_ROUTE_MATRIX` to calculate distances and durations between multiple origins and destinations.\n```\nTool: GOOGLE_MAPS_COMPUTE_ROUTE_MATRIX\nParameters:\n  - origins (required): Array of origin locations (address strings or lat/lng objects)\n  - destinations (required): Array of destination locations\n  - travelMode: DRIVE, BICYCLE, WALK, TWO_WHEELER, or TRANSIT\n  - routingPreference: TRAFFIC_UNAWARE, TRAFFIC_AWARE, TRAFFIC_AWARE_OPTIMAL\n  - fieldMask: Response fields to include\n  - units: METRIC or IMPERIAL\n```\n\n### 5. Get Place Details\nUse `GOOGLE_MAPS_GET_PLACE_DETAILS` to retrieve comprehensive information about a specific place.\n```\nTool: GOOGLE_MAPS_GET_PLACE_DETAILS\nDescription: Retrieves comprehensive details for a place using its resource\n  name (places/{place_id} format). Returns hours, contacts, reviews, etc.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n### 6. Search Nearby Places\nUse `GOOGLE_MAPS_NEARBY_SEARCH` to find places within a circular area around a point.\n```\nTool: GOOGLE_MAPS_NEARBY_SEARCH\nParameters:\n  - latitude (required): Center latitude (-90 to 90)\n  - longitude (required): Center longitude (-180 to 180)\n  - radius (required): Search radius in meters (max 50000)\n  - includedTypes: Place types to include (e.g., [\"restaurant\", \"cafe\"])\n  - excludedTypes: Place types to exclude\n  - fieldMask: Fields to return\n  - maxResultCount: Max results (1-20)\n```\n\n## Common Patterns\n\n- **Geocode then route**: Use `GOOGLE_MAPS_GEOCODING_API` to convert addresses to coordinates, then `GOOGLE_MAPS_GET_ROUTE` for directions between them.\n- **Search then detail**: Use `GOOGLE_MAPS_TEXT_SEARCH` to find places, then `GOOGLE_MAPS_GET_PLACE_DETAILS` for richer metadata (hours, contacts, reviews).\n- **Autocomplete UX**: Use `GOOGLE_MAPS_AUTOCOMPLETE` for type-ahead search suggestions as users type addresses or place names.\n- **Reverse geocode**: Use `GOOGLE_MAPS_GEOCODE_LOCATION` to convert coordinates back to a human-readable address.\n- **Batch distance calculation**: Use `GOOGLE_MAPS_COMPUTE_ROUTE_MATRIX` for many-to-many distance calculations instead of calling `GOOGLE_MAPS_GET_ROUTE` repeatedly.\n- **Embed maps**: Use `GOOGLE_MAPS_MAPS_EMBED_API` to generate embeddable map URLs for places, directions, or search results.\n\n## Known Pitfalls\n\n- **Route matrix results structure**: `GOOGLE_MAPS_COMPUTE_ROUTE_MATRIX` returns results under `data.elements` with `originIndex` and `destinationIndex` plus `distanceMeters` and `duration` -- not a `routes[]` structure.\n- **Duration format**: `GOOGLE_MAPS_GET_ROUTE` returns durations as strings like `\"937s\"` inside `data.response_data.routes`. You must parse these before numeric comparisons.\n- **Place IDs for chaining**: Use place identifiers returned from `GOOGLE_MAPS_TEXT_SEARCH` when calling `GOOGLE_MAPS_GET_PLACE_DETAILS` for richer fields.\n- **Reverse geocoding input**: `GOOGLE_MAPS_GEOCODE_LOCATION` is coordinate-driven. Ensure you pass lat/lng (not an address string) to avoid mismatched lookups.\n- **Routing preference restrictions**: `routingPreference` cannot be set when `travelMode` is WALK, BICYCLE, or TRANSIT -- it must be omitted for these modes.\n- **Nearby search type validity**: `\"food\"` is NOT a valid type for `GOOGLE_MAPS_NEARBY_SEARCH` (it is Table B). Use specific types like `restaurant`, `cafe`, `bakery`, `fast_food_restaurant` instead.\n- **Embed API uses API keys only**: `GOOGLE_MAPS_MAPS_EMBED_API` requires an API key and does not support OAuth2.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| Geocode address | `GOOGLE_MAPS_GEOCODING_API` | `address` or `latlng` or `place_id` |\n| Reverse geocode | `GOOGLE_MAPS_GEOCODE_LOCATION` | (see full schema via RUBE_SEARCH_TOOLS) |\n| Text search | `GOOGLE_MAPS_TEXT_SEARCH` | `textQuery`, `fieldMask`, `maxResultCount` |\n| Nearby search | `GOOGLE_MAPS_NEARBY_SEARCH` | `latitude`, `longitude`, `radius`, `includedTypes` |\n| Get directions | `GOOGLE_MAPS_GET_ROUTE` | `origin_address`, `destination_address`, `travelMode` |\n| Distance matrix | `GOOGLE_MAPS_COMPUTE_ROUTE_MATRIX` | `origins`, `destinations`, `travelMode` |\n| Place details | `GOOGLE_MAPS_GET_PLACE_DETAILS` | (see full schema via RUBE_SEARCH_TOOLS) |\n| Autocomplete | `GOOGLE_MAPS_AUTOCOMPLETE` | `input`, `includedRegionCodes`, `locationBias` |\n| Place photo | `GOOGLE_MAPS_PLACE_PHOTO` | (see full schema via RUBE_SEARCH_TOOLS) |\n| Embed map | `GOOGLE_MAPS_MAPS_EMBED_API` | `mode`, plus mode-specific params |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google-search-console-automation/SKILL.md",
    "content": "---\nname: google-search-console-automation\ndescription: \"Automate Google Search Console tasks via Rube MCP (Composio): query search analytics, list sites, inspect URLs, submit sitemaps, monitor search performance. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Search Console Automation via Rube MCP\n\nQuery search analytics, inspect URLs, manage sitemaps, and monitor search performance using Google Search Console via Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/google_search_console](https://composio.dev/toolkits/google_search_console)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_search_console`\n- Verified site ownership or appropriate permissions in Google Search Console\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_search_console`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. List All Verified Sites\nUse `GOOGLE_SEARCH_CONSOLE_LIST_SITES` to retrieve all sites the authenticated user owns or has access to.\n```\nTool: GOOGLE_SEARCH_CONSOLE_LIST_SITES\nParameters: (none required)\nReturns: List of site entries with siteUrl and permissionLevel\n```\n\n### 2. Query Search Analytics\nUse `GOOGLE_SEARCH_CONSOLE_SEARCH_ANALYTICS_QUERY` to get search performance data including clicks, impressions, CTR, and position.\n```\nTool: GOOGLE_SEARCH_CONSOLE_SEARCH_ANALYTICS_QUERY\nParameters:\n  - site_url (required): Site URL (e.g., \"https://www.example.com/\" or \"sc-domain:example.com\")\n  - start_date (required): Start date in YYYY-MM-DD format\n  - end_date (required): End date in YYYY-MM-DD format\n  - dimensions: Group by [\"query\", \"page\", \"country\", \"device\", \"date\", \"searchAppearance\"]\n  - search_type: \"web\" (default), \"image\", \"video\", \"news\", \"discover\", \"googleNews\"\n  - dimension_filter_groups: Filters for dimensions (operator: equals, notEquals, contains, notContains, includingRegex, excludingRegex)\n  - row_limit: Max rows (1-25000, default 1000)\n  - start_row: Pagination offset (default 0)\n  - aggregation_type: \"auto\", \"byPage\", \"byProperty\", \"byNewsShowcasePanel\"\n  - data_state: \"final\" (default), \"all\", \"hourly_all\"\n```\n\n### 3. Inspect a URL\nUse `GOOGLE_SEARCH_CONSOLE_INSPECT_URL` to check the indexing status and issues for a specific URL.\n```\nTool: GOOGLE_SEARCH_CONSOLE_INSPECT_URL\nParameters:\n  - inspection_url (required): Full URL to inspect (e.g., \"https://www.example.com/page\")\n  - site_url (required): Property URL (e.g., \"https://www.example.com/\")\n  - language_code: BCP-47 language (default: \"en-US\")\n```\n\n### 4. List Sitemaps\nUse `GOOGLE_SEARCH_CONSOLE_LIST_SITEMAPS` to retrieve all sitemaps submitted for a site.\n```\nTool: GOOGLE_SEARCH_CONSOLE_LIST_SITEMAPS\nParameters:\n  - site_url (required): Site URL (e.g., \"https://www.example.com/\")\n  - sitemap_index: Specific sitemap index URL to list sitemaps from\n```\n\n### 5. Submit a Sitemap\nUse `GOOGLE_SEARCH_CONSOLE_SUBMIT_SITEMAP` to register or resubmit a sitemap for indexing.\n```\nTool: GOOGLE_SEARCH_CONSOLE_SUBMIT_SITEMAP\nParameters:\n  - site_url (required): Site URL or domain property (e.g., \"sc-domain:example.com\")\n  - feedpath (required): Full sitemap URL (e.g., \"https://www.example.com/sitemap.xml\")\n```\n\n### 6. Get Sitemap Details\nUse `GOOGLE_SEARCH_CONSOLE_GET_SITEMAP` to retrieve information about a specific submitted sitemap.\n```\nTool: GOOGLE_SEARCH_CONSOLE_GET_SITEMAP\nParameters:\n  - site_url (required): Site URL\n  - feedpath (required): Sitemap URL to retrieve details for\n```\n\n## Common Patterns\n\n- **Performance monitoring**: Use `GOOGLE_SEARCH_CONSOLE_SEARCH_ANALYTICS_QUERY` with `dimensions: [\"date\"]` over a date range to track daily search performance trends.\n- **Top queries report**: Use `GOOGLE_SEARCH_CONSOLE_SEARCH_ANALYTICS_QUERY` with `dimensions: [\"query\"]` to find the most clicked search terms.\n- **Page-level analysis**: Use `dimensions: [\"page\"]` to identify top-performing pages, then `dimensions: [\"query\", \"page\"]` to see which queries drive traffic to each page.\n- **Indexing audit**: Use `GOOGLE_SEARCH_CONSOLE_INSPECT_URL` to check the indexing status of important pages.\n- **Sitemap management**: Use `GOOGLE_SEARCH_CONSOLE_LIST_SITEMAPS` to verify submitted sitemaps, then `GOOGLE_SEARCH_CONSOLE_SUBMIT_SITEMAP` to submit new or updated ones.\n- **Country/device breakdown**: Use `dimensions: [\"country\", \"device\"]` to understand geographic and device-type distribution of search traffic.\n- **Filter for specific queries**: Use `dimension_filter_groups` with `contains` or `includingRegex` operators to focus on specific keyword groups.\n\n## Known Pitfalls\n\n- **Site URL format matters**: URL-prefix properties use the full URL with protocol and trailing slash (e.g., `https://www.example.com/`). Domain properties use the `sc-domain:` prefix (e.g., `sc-domain:example.com`). Using the wrong format will return empty results or errors.\n- **Date range limits**: Data is typically available with a 2-3 day delay. `data_state: \"all\"` includes fresher data that may still change. `hourly_all` only works for dates within the last 3 days.\n- **Row limit pagination**: The API returns top results sorted by clicks (or by date when grouping by date). For complete data, paginate using `start_row` with the `row_limit`.\n- **Max 25,000 rows per request**: Even with pagination, each request returns at most 25,000 rows. For very large datasets, narrow your date range or add dimension filters.\n- **Inspection URL must match site**: The `inspection_url` must be a page under the `site_url` property. Cross-property inspections will fail.\n- **Sitemap must be accessible**: `GOOGLE_SEARCH_CONSOLE_SUBMIT_SITEMAP` requires the sitemap file to be publicly accessible at the specified URL and properly formatted as XML.\n- **Results sorted by clicks**: By default, analytics results are sorted by click count descending, except when grouping by `date` (which sorts by date ascending).\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| List sites | `GOOGLE_SEARCH_CONSOLE_LIST_SITES` | (none) |\n| Search analytics | `GOOGLE_SEARCH_CONSOLE_SEARCH_ANALYTICS_QUERY` | `site_url`, `start_date`, `end_date`, `dimensions` |\n| Inspect URL | `GOOGLE_SEARCH_CONSOLE_INSPECT_URL` | `inspection_url`, `site_url` |\n| List sitemaps | `GOOGLE_SEARCH_CONSOLE_LIST_SITEMAPS` | `site_url` |\n| Submit sitemap | `GOOGLE_SEARCH_CONSOLE_SUBMIT_SITEMAP` | `site_url`, `feedpath` |\n| Get sitemap info | `GOOGLE_SEARCH_CONSOLE_GET_SITEMAP` | `site_url`, `feedpath` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/google_admin-automation/SKILL.md",
    "content": "---\nname: google_admin-automation\ndescription: \"Automate Google Admin tasks via Rube MCP (Composio): user management, org units, groups, and domain administration. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Admin Automation via Rube MCP\n\nAutomate Google Admin operations through Composio's Google Admin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_admin](https://composio.dev/toolkits/google_admin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Admin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_admin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_admin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"user management, org units, groups, and domain administration\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Google Admin\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Google Admin Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Google Admin tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Google Admin Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Google Admin operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Google Admin connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Admin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_admin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/google_admin](https://composio.dev/toolkits/google_admin)\n"
  },
  {
    "path": "composio-skills/google_classroom-automation/SKILL.md",
    "content": "---\nname: google_classroom-automation\ndescription: \"Automate Google Classroom tasks via Rube MCP (Composio): course management, assignments, student rosters, and announcements. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Classroom Automation via Rube MCP\n\nAutomate Google Classroom operations through Composio's Google Classroom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_classroom](https://composio.dev/toolkits/google_classroom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Classroom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"course management, assignments, student rosters, and announcements\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Google Classroom\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Google Classroom Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Google Classroom tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Google Classroom Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Google Classroom operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Google Classroom connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Classroom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_classroom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/google_classroom](https://composio.dev/toolkits/google_classroom)\n"
  },
  {
    "path": "composio-skills/google_maps-automation/SKILL.md",
    "content": "---\nname: google_maps-automation\ndescription: \"Automate Google Maps tasks via Rube MCP (Composio): geocoding, directions, place search, and distance calculations. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Maps Automation via Rube MCP\n\nAutomate Google Maps operations through Composio's Google Maps toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_maps](https://composio.dev/toolkits/google_maps)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Maps connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_maps`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_maps`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"geocoding, directions, place search, and distance calculations\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Google Maps\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Google Maps Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Google Maps tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Google Maps Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Google Maps operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Google Maps connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Maps-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_maps` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/google_maps](https://composio.dev/toolkits/google_maps)\n"
  },
  {
    "path": "composio-skills/google_search_console-automation/SKILL.md",
    "content": "---\nname: google_search_console-automation\ndescription: \"Automate Google Search Console tasks via Rube MCP (Composio): search performance, URL inspection, sitemaps, and indexing status. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Search Console Automation via Rube MCP\n\nAutomate Google Search Console operations through Composio's Google Search Console toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/google_search_console](https://composio.dev/toolkits/google_search_console)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Search Console connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_search_console`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_search_console`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"search performance, URL inspection, sitemaps, and indexing status\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Google Search Console\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Google Search Console Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Google Search Console tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Google Search Console Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Google Search Console operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Google Search Console connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Search Console-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `google_search_console` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/google_search_console](https://composio.dev/toolkits/google_search_console)\n"
  },
  {
    "path": "composio-skills/googleads-automation/SKILL.md",
    "content": "---\nname: googleads-automation\ndescription: \"Automate Google Ads analytics tasks via Rube MCP (Composio): list Google Ads links, run GA4 reports, check compatibility, list properties and accounts. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Ads Automation via Rube MCP\n\nAccess Google Ads data through Google Analytics integration, run performance reports, list linked Ads accounts, and analyze campaign metrics using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googleads](https://composio.dev/toolkits/googleads)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `google_analytics`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `google_analytics`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n> **Note**: Google Ads data is accessed through the Google Analytics toolkit integration. The tools below use GA4 properties linked to Google Ads accounts.\n\n## Core Workflows\n\n### 1. List Google Ads Links for a Property\nUse `GOOGLE_ANALYTICS_ANALYTICS_ADMIN_PROPERTIES_GOOGLE_ADS` to retrieve all Google Ads account links configured for a GA4 property.\n```\nTool: GOOGLE_ANALYTICS_ANALYTICS_ADMIN_PROPERTIES_GOOGLE_ADS\nParameters:\n  - parent (required): Property resource name (format: \"properties/{propertyId}\")\n  - pageSize: Max results (1-200, default 50)\n  - pageToken: Pagination token\n```\n\n### 2. Run a GA4 Performance Report\nUse `GOOGLE_ANALYTICS_RUN_REPORT` to run customized reports with dimensions, metrics, date ranges, and filters.\n```\nTool: GOOGLE_ANALYTICS_RUN_REPORT\nParameters:\n  - property (required): Property resource (format: \"properties/{property_id}\")\n  - dimensions: Array of dimension objects (e.g., [{\"name\": \"sessionCampaignName\"}, {\"name\": \"date\"}])\n  - metrics: Array of metric objects (e.g., [{\"name\": \"sessions\"}, {\"name\": \"totalRevenue\"}])\n  - dateRanges: Array with startDate and endDate (e.g., [{\"startDate\": \"2025-01-01\", \"endDate\": \"2025-01-31\"}])\n  - dimensionFilter: Filter by dimension values\n  - metricFilter: Filter by metric values (applied after aggregation)\n  - orderBys: Sort results\n  - limit: Max rows to return (1-250000)\n```\n\n### 3. Check Dimension/Metric Compatibility\nUse `GOOGLE_ANALYTICS_CHECK_COMPATIBILITY` to validate dimension and metric combinations before running a report.\n```\nTool: GOOGLE_ANALYTICS_CHECK_COMPATIBILITY\nDescription: Validates compatibility of chosen dimensions or metrics\n  before running a report.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n### 4. List GA4 Accounts\nUse `GOOGLE_ANALYTICS_LIST_ACCOUNTS` to enumerate all accessible Google Analytics accounts.\n```\nTool: GOOGLE_ANALYTICS_LIST_ACCOUNTS\nParameters:\n  - pageSize: Max accounts to return\n  - pageToken: Pagination token\n  - showDeleted: Include soft-deleted accounts\n```\n\n### 5. List GA4 Properties Under an Account\nUse `GOOGLE_ANALYTICS_LIST_PROPERTIES` to list properties for a specific GA4 account.\n```\nTool: GOOGLE_ANALYTICS_LIST_PROPERTIES\nParameters:\n  - account (required): Account resource name (format: \"accounts/{account_id}\")\n  - pageSize: Max properties (1-200)\n  - pageToken: Pagination token\n  - showDeleted: Include trashed properties\n```\n\n### 6. Get Available Dimensions and Metrics\nUse `GOOGLE_ANALYTICS_GET_METADATA` to discover all available fields for building reports.\n```\nTool: GOOGLE_ANALYTICS_GET_METADATA\nDescription: Gets metadata for dimensions, metrics, and comparisons\n  for a GA4 property.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n## Common Patterns\n\n- **Discover then report**: Use `GOOGLE_ANALYTICS_LIST_ACCOUNTS` to find account IDs, then `GOOGLE_ANALYTICS_LIST_PROPERTIES` to find property IDs, then `GOOGLE_ANALYTICS_RUN_REPORT` to pull data.\n- **Validate before querying**: Use `GOOGLE_ANALYTICS_CHECK_COMPATIBILITY` to validate dimension/metric combinations before running reports to avoid 400 errors.\n- **Campaign performance**: Run reports with dimensions like `sessionCampaignName`, `sessionSource`, `sessionMedium` and metrics like `sessions`, `activeUsers`, `totalRevenue`.\n- **Ads link discovery**: Use `GOOGLE_ANALYTICS_ANALYTICS_ADMIN_PROPERTIES_GOOGLE_ADS` to find which Google Ads accounts are linked to each GA4 property.\n- **Field discovery**: Use `GOOGLE_ANALYTICS_GET_METADATA` to list all available dimensions and metrics before constructing complex reports.\n\n## Known Pitfalls\n\n- **Dimension/metric compatibility**: The GA4 API has strict compatibility rules. Not all dimensions can be combined with all metrics. Demographic dimensions (e.g., `userAgeBracket`, `userGender`) are often incompatible with session-scoped dimensions/filters (e.g., `sessionCampaignName`, `sessionSource`).\n- **`dateRange` is NOT a dimension**: Do not include `dateRange` in the dimensions array. Use `date`, `dateHour`, `year`, `month`, or `week` instead.\n- **`exits` is NOT valid**: Neither `exits` as a dimension nor as a metric is valid in GA4.\n- **Property ID format**: Must be `properties/{numeric_id}` (e.g., `properties/123456789`). Do not use Google Account IDs (long OAuth IDs).\n- **Account ID format**: Must be `accounts/{numeric_id}` where the numeric ID is 6-10 digits.\n- **Filter separation**: Use `dimensionFilter` only for dimension fields and `metricFilter` only for metric fields. Mixing them will cause errors.\n- **Max 9 dimensions and 10 metrics** per report request.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| List Ads links | `GOOGLE_ANALYTICS_ANALYTICS_ADMIN_PROPERTIES_GOOGLE_ADS` | `parent` |\n| Run report | `GOOGLE_ANALYTICS_RUN_REPORT` | `property`, `dimensions`, `metrics`, `dateRanges` |\n| Check compatibility | `GOOGLE_ANALYTICS_CHECK_COMPATIBILITY` | (see full schema via RUBE_SEARCH_TOOLS) |\n| List accounts | `GOOGLE_ANALYTICS_LIST_ACCOUNTS` | `pageSize` |\n| List properties | `GOOGLE_ANALYTICS_LIST_PROPERTIES` | `account`, `pageSize` |\n| Get metadata | `GOOGLE_ANALYTICS_GET_METADATA` | (see full schema via RUBE_SEARCH_TOOLS) |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googlebigquery-automation/SKILL.md",
    "content": "---\nname: googlebigquery-automation\ndescription: \"Automate Google BigQuery tasks via Rube MCP (Composio): run SQL queries, explore datasets and metadata, execute MBQL queries via Metabase integration. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google BigQuery Automation via Rube MCP\n\nRun SQL queries, explore database schemas, and analyze datasets through the Metabase integration using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googlebigquery](https://composio.dev/toolkits/googlebigquery)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `metabase`\n- A Metabase instance connected to your BigQuery data source\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `metabase`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n> **Note**: BigQuery data is accessed through Metabase, a business intelligence tool that connects to BigQuery as a data source. The tools below execute queries and retrieve metadata through Metabase's API.\n\n## Core Workflows\n\n### 1. Run a Native SQL Query\nUse `METABASE_POST_API_DATASET` with type `native` to execute raw SQL queries against your BigQuery database.\n```\nTool: METABASE_POST_API_DATASET\nParameters:\n  - database (required): Metabase database ID (integer)\n  - type (required): \"native\" for SQL queries\n  - native (required): Object with \"query\" string\n    - query: Raw SQL string (e.g., \"SELECT * FROM users LIMIT 10\")\n    - template_tags: Parameterized query variables (optional)\n  - constraints: { \"max-results\": 1000 } (optional)\n```\n\n### 2. Run a Structured MBQL Query\nUse `METABASE_POST_API_DATASET` with type `query` for Metabase Query Language queries with built-in aggregation and filtering.\n```\nTool: METABASE_POST_API_DATASET\nParameters:\n  - database (required): Metabase database ID\n  - type (required): \"query\" for MBQL\n  - query (required): Object with:\n    - source-table: Table ID (integer)\n    - aggregation: e.g., [[\"count\"]] or [[\"sum\", [\"field\", 5, null]]]\n    - breakout: Group-by fields\n    - filter: Filter conditions\n    - limit: Max rows\n    - order-by: Sort fields\n```\n\n### 3. Get Query Metadata\nUse `METABASE_POST_API_DATASET_QUERY_METADATA` to retrieve metadata about databases, tables, and fields available for querying.\n```\nTool: METABASE_POST_API_DATASET_QUERY_METADATA\nParameters:\n  - database (required): Metabase database ID\n  - type (required): \"query\" or \"native\"\n  - query (required): Query object (e.g., {\"source-table\": 1})\n```\n\n### 4. Convert Query to Native SQL\nUse `METABASE_POST_API_DATASET_NATIVE` to convert an MBQL query into its native SQL representation.\n```\nTool: METABASE_POST_API_DATASET_NATIVE\nParameters:\n  - database (required): Metabase database ID\n  - type (required): \"native\"\n  - native (required): Object with \"query\" and optional \"template_tags\"\n  - parameters: Query parameter values (optional)\n```\n\n### 5. List Available Databases\nUse `METABASE_GET_API_DATABASE` to discover all database connections configured in Metabase.\n```\nTool: METABASE_GET_API_DATABASE\nDescription: Retrieves a list of all Database instances configured in Metabase.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n### 6. Get Database Schema Metadata\nUse `METABASE_GET_API_DATABASE_ID_METADATA` to retrieve complete table and field information for a specific database.\n```\nTool: METABASE_GET_API_DATABASE_ID_METADATA\nDescription: Retrieves complete metadata for a specific database including\n  all tables and fields.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n## Common Patterns\n\n- **Discover then query**: Use `METABASE_GET_API_DATABASE` to find database IDs, then `METABASE_GET_API_DATABASE_ID_METADATA` to explore tables and fields, then `METABASE_POST_API_DATASET` to run queries.\n- **SQL-first approach**: Use `METABASE_POST_API_DATASET` with `type: \"native\"` and write standard SQL queries for maximum flexibility.\n- **Parameterized queries**: Use `template_tags` in native queries for safe parameterization (e.g., `SELECT * FROM users WHERE id = {{user_id}}`).\n- **Schema exploration**: Use `METABASE_POST_API_DATASET_QUERY_METADATA` to understand table structures before building complex queries.\n- **Get parameter values**: Use `METABASE_POST_API_DATASET_PARAMETER_VALUES` to retrieve possible values for filter dropdowns.\n\n## Known Pitfalls\n\n- The `database` parameter is a Metabase-internal **integer ID**, not the BigQuery project or dataset name. Use `METABASE_GET_API_DATABASE` to find valid database IDs first.\n- `source-table` in MBQL queries is also a Metabase-internal integer, not the BigQuery table name. Discover table IDs via metadata tools.\n- Native SQL queries use BigQuery SQL dialect (Standard SQL). Ensure your syntax is BigQuery-compatible.\n- `max-results` in constraints defaults can limit returned rows. Set explicitly for large result sets.\n- Responses from `METABASE_POST_API_DATASET` contain results nested under `data` -- parse carefully as the structure may be deeply nested.\n- Metabase field IDs used in MBQL `aggregation`, `breakout`, and `filter` arrays must be integers obtained from metadata responses.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| Run SQL query | `METABASE_POST_API_DATASET` | `database`, `type: \"native\"`, `native.query` |\n| Run MBQL query | `METABASE_POST_API_DATASET` | `database`, `type: \"query\"`, `query` |\n| Get query metadata | `METABASE_POST_API_DATASET_QUERY_METADATA` | `database`, `type`, `query` |\n| Convert to SQL | `METABASE_POST_API_DATASET_NATIVE` | `database`, `type`, `native` |\n| Get parameter values | `METABASE_POST_API_DATASET_PARAMETER_VALUES` | `parameter`, `field_ids` |\n| List databases | `METABASE_GET_API_DATABASE` | (see full schema via RUBE_SEARCH_TOOLS) |\n| Get database metadata | `METABASE_GET_API_DATABASE_ID_METADATA` | (see full schema via RUBE_SEARCH_TOOLS) |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googlecalendar-automation/SKILL.md",
    "content": "---\nname: googlecalendar-automation\ndescription: \"Automate Google Calendar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Calendar Automation via Rube MCP\n\nAutomate Google Calendar operations through Composio's Google Calendar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/googlecalendar](https://composio.dev/toolkits/googlecalendar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Calendar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googlecalendar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googlecalendar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Calendar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Calendar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"googlecalendar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Calendar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `googlecalendar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googledocs-automation/SKILL.md",
    "content": "---\nname: googledocs-automation\ndescription: \"Automate Google Docs tasks via Rube MCP (Composio): create, edit, search, export, copy, and update documents. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Docs Automation via Rube MCP\n\nCreate, edit, search, export, and manage Google Docs documents programmatically using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googledocs](https://composio.dev/toolkits/googledocs)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googledocs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googledocs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. Create a New Document\nUse `GOOGLEDOCS_CREATE_DOCUMENT` to create a new Google Doc with a title and initial text content.\n```\nTool: GOOGLEDOCS_CREATE_DOCUMENT\nParameters:\n  - title (required): Document filename/title\n  - text (required): Initial text content to insert into the document\n```\n\n### 2. Search for Documents\nUse `GOOGLEDOCS_SEARCH_DOCUMENTS` to find Google Docs by name, content, date, or sharing status.\n```\nTool: GOOGLEDOCS_SEARCH_DOCUMENTS\nParameters:\n  - query: Search query string\n  - max_results: Limit number of results\n  - modified_after / created_after: Filter by date\n  - shared_with_me: Filter shared documents\n  - starred_only: Filter starred documents\n  - include_shared_drives: Search shared drives\n  - order_by: Sort results\n  - page_token: Pagination token\n```\n\n### 3. Update Document Content with Markdown\nUse `GOOGLEDOCS_UPDATE_DOCUMENT_MARKDOWN` to replace the entire content of a document with Markdown-formatted text.\n```\nTool: GOOGLEDOCS_UPDATE_DOCUMENT_MARKDOWN\nParameters:\n  - id (required): Document ID\n  - markdown (required): Markdown content to replace entire document body\n```\n\n### 4. Find and Replace Text\nUse `GOOGLEDOCS_REPLACE_ALL_TEXT` to replace all occurrences of a string in a document.\n```\nTool: GOOGLEDOCS_REPLACE_ALL_TEXT\nParameters:\n  - document_id (required): Target document ID\n  - find_text (required): Text to search for\n  - replace_text (required): Replacement text\n  - match_case: Case-sensitive matching (boolean)\n  - search_by_regex: Use regex for find_text\n  - tab_ids: Specific tabs to search\n```\n\n### 5. Export Document as PDF\nUse `GOOGLEDOCS_EXPORT_DOCUMENT_AS_PDF` to export a Google Doc to PDF format.\n```\nTool: GOOGLEDOCS_EXPORT_DOCUMENT_AS_PDF\nParameters:\n  - file_id (required): Document file ID\n  - filename: Output PDF filename\n```\n\n### 6. Copy a Document\nUse `GOOGLEDOCS_COPY_DOCUMENT` to duplicate an existing Google Doc.\n```\nTool: GOOGLEDOCS_COPY_DOCUMENT\nParameters:\n  - document_id (required): Source document ID to copy\n  - title: Title for the new copy\n  - include_shared_drives: Search shared drives for the source\n```\n\n## Common Patterns\n\n- **Search then edit**: Use `GOOGLEDOCS_SEARCH_DOCUMENTS` to find a document by name, then use the returned document ID with `GOOGLEDOCS_UPDATE_DOCUMENT_MARKDOWN` or `GOOGLEDOCS_REPLACE_ALL_TEXT` to modify it.\n- **Create from template**: Use `GOOGLEDOCS_COPY_DOCUMENT` to duplicate a template, then `GOOGLEDOCS_REPLACE_ALL_TEXT` to fill in placeholder text.\n- **Retrieve then update**: Use `GOOGLEDOCS_GET_DOCUMENT_BY_ID` to read current content, then apply edits with `GOOGLEDOCS_UPDATE_EXISTING_DOCUMENT`.\n- **Batch text insertion**: Use `GOOGLEDOCS_INSERT_TEXT_ACTION` to insert text at specific positions (by index) or append to the end of a document.\n- **Share documents**: Combine with `GOOGLEDRIVE_ADD_FILE_SHARING_PREFERENCE` (googledrive toolkit) to share documents after creation.\n\n## Known Pitfalls\n\n- `GOOGLEDOCS_UPDATE_DOCUMENT_MARKDOWN` replaces the **entire** document content -- it does not append. Use it for full rewrites only.\n- `GOOGLEDOCS_INSERT_TEXT_ACTION` requires a precise `insertion_index` (character position). Set `append_to_end: true` to safely add text at the end.\n- `GOOGLEDOCS_UPDATE_EXISTING_DOCUMENT` requires constructing an `editDocs` request body with raw Google Docs API batch update requests -- consult the API documentation for the correct structure.\n- Document IDs and file IDs are the same value for Google Docs, but parameter names differ across tools (`id`, `document_id`, `file_id`).\n- `GOOGLEDOCS_SEARCH_DOCUMENTS` uses Google Drive search syntax for the `query` parameter (e.g., `name contains 'report'`).\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| Create document | `GOOGLEDOCS_CREATE_DOCUMENT` | `title`, `text` |\n| Search documents | `GOOGLEDOCS_SEARCH_DOCUMENTS` | `query`, `max_results`, `modified_after` |\n| Get document by ID | `GOOGLEDOCS_GET_DOCUMENT_BY_ID` | `id` |\n| Update with Markdown | `GOOGLEDOCS_UPDATE_DOCUMENT_MARKDOWN` | `id`, `markdown` |\n| Programmatic edits | `GOOGLEDOCS_UPDATE_EXISTING_DOCUMENT` | `document_id`, `editDocs` |\n| Insert text | `GOOGLEDOCS_INSERT_TEXT_ACTION` | `document_id`, `text_to_insert`, `insertion_index` |\n| Find and replace | `GOOGLEDOCS_REPLACE_ALL_TEXT` | `document_id`, `find_text`, `replace_text` |\n| Export as PDF | `GOOGLEDOCS_EXPORT_DOCUMENT_AS_PDF` | `file_id`, `filename` |\n| Copy document | `GOOGLEDOCS_COPY_DOCUMENT` | `document_id`, `title` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googledrive-automation/SKILL.md",
    "content": "---\nname: googledrive-automation\ndescription: \"Automate Google Drive tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Drive Automation via Rube MCP\n\nAutomate Google Drive operations through Composio's Google Drive toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/googledrive](https://composio.dev/toolkits/googledrive)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Drive connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googledrive`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googledrive`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Drive operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Drive task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"googledrive\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Drive-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `googledrive` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googlemeet-automation/SKILL.md",
    "content": "---\nname: googlemeet-automation\ndescription: \"Automate Google Meet tasks via Rube MCP (Composio): create Meet spaces, schedule video conferences via Calendar events, manage meeting access. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Meet Automation via Rube MCP\n\nCreate Google Meet video conferences, schedule meetings with Meet links, and manage meeting spaces using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googlemeet](https://composio.dev/toolkits/googlemeet)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googlemeet`\n- For scheduling meetings with attendees, also connect the `googlecalendar` toolkit\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googlemeet`\n3. Optionally also connect `googlecalendar` for scheduling meetings with calendar events\n4. If connection is not ACTIVE, follow the returned auth link to complete setup\n5. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. Create a Standalone Meet Space\nUse `GOOGLEMEET_CREATE_MEET` to create a new Google Meet meeting space with optional access configuration.\n```\nTool: GOOGLEMEET_CREATE_MEET\nDescription: Creates a new Google Meet space, optionally configuring\n  its access type and entry points.\nNote: Call RUBE_SEARCH_TOOLS to get the full schema for this tool.\n```\n\n### 2. Schedule a Meeting with Google Meet Link\nUse `GOOGLECALENDAR_CREATE_EVENT` to create a calendar event that automatically generates a Google Meet link (enabled by default).\n```\nTool: GOOGLECALENDAR_CREATE_EVENT\nParameters:\n  - start_datetime (required): ISO 8601 format (e.g., \"2025-01-16T13:00:00\")\n  - summary: Meeting title\n  - attendees: List of email addresses\n  - timezone: IANA timezone (e.g., \"America/New_York\")\n  - event_duration_hour: Duration hours (default: 0)\n  - event_duration_minutes: Duration minutes (default: 30, max: 59)\n  - create_meeting_room: true (default) -- generates Meet link\n  - description: Meeting agenda/notes\n  - location: Physical or virtual location\n```\n\n### 3. Find Available Time Slots\nUse `GOOGLECALENDAR_FIND_FREE_SLOTS` before scheduling to find when participants are available.\n```\nTool: GOOGLECALENDAR_FIND_FREE_SLOTS\nParameters:\n  - items: List of calendar IDs to check (e.g., [\"primary\", \"user@example.com\"])\n  - time_min: Start of time window (ISO format)\n  - time_max: End of time window (ISO format)\n  - timezone: IANA timezone\n```\n\n### 4. Update an Existing Meeting\nUse `GOOGLECALENDAR_PATCH_EVENT` to modify meeting details, reschedule, or update attendees.\n```\nTool: GOOGLECALENDAR_PATCH_EVENT\nParameters:\n  - calendar_id (required): Calendar ID (use \"primary\")\n  - event_id (required): Event ID (from search/list)\n  - summary: Updated title\n  - start_time / end_time: Rescheduled times\n  - attendees: Updated attendee list (replaces existing)\n  - send_updates: Notification preference (\"all\", \"externalOnly\", \"none\")\n```\n\n## Common Patterns\n\n- **Quick meeting link**: Use `GOOGLEMEET_CREATE_MEET` for an instant meeting space without a calendar event.\n- **Scheduled meeting with attendees**: Use `GOOGLECALENDAR_CREATE_EVENT` with `create_meeting_room: true` (default) to create a calendar event with an embedded Meet link. Workspace accounts get a Meet link automatically.\n- **Check availability first**: Use `GOOGLECALENDAR_FIND_FREE_SLOTS` to find open time slots before scheduling with `GOOGLECALENDAR_CREATE_EVENT`.\n- **Resolve names to emails**: Use `GMAIL_SEARCH_PEOPLE` (gmail toolkit) to look up email addresses from names before adding attendees.\n- **Get current time**: Use `GOOGLECALENDAR_GET_CURRENT_DATE_TIME` with a timezone to get the current date/time for scheduling relative to \"now\".\n\n## Known Pitfalls\n\n- **Attendees must be email addresses**: `GOOGLECALENDAR_CREATE_EVENT` only accepts email addresses for attendees, not names. Use `GMAIL_SEARCH_PEOPLE` to resolve names to emails first.\n- **Personal Gmail vs Workspace**: The `create_meeting_room` feature works best with Google Workspace accounts. Personal Gmail accounts will gracefully fallback to creating an event without a Meet link.\n- **start_datetime format**: Must be exact ISO 8601 (e.g., `2025-01-16T13:00:00`). Natural language like \"tomorrow at 3pm\" is NOT supported.\n- **Duration limits**: `event_duration_minutes` max is 59. For 1+ hour meetings, use `event_duration_hour` combined with `event_duration_minutes`.\n- **Timezone is critical**: Always provide `timezone` as a valid IANA identifier (e.g., `America/New_York`). Abbreviations like \"EST\" or \"PST\" are NOT valid.\n- **Event IDs are opaque**: To update or delete events, you must first retrieve the event ID using a search or list tool.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| Create Meet space | `GOOGLEMEET_CREATE_MEET` | (see full schema via RUBE_SEARCH_TOOLS) |\n| Schedule meeting | `GOOGLECALENDAR_CREATE_EVENT` | `start_datetime`, `summary`, `attendees`, `timezone` |\n| Find free slots | `GOOGLECALENDAR_FIND_FREE_SLOTS` | `items`, `time_min`, `time_max`, `timezone` |\n| Update meeting | `GOOGLECALENDAR_PATCH_EVENT` | `calendar_id`, `event_id`, `summary`, `start_time` |\n| Get current time | `GOOGLECALENDAR_GET_CURRENT_DATE_TIME` | `timezone` |\n| Look up contacts | `GMAIL_SEARCH_PEOPLE` | `query` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googlephotos-automation/SKILL.md",
    "content": "---\nname: googlephotos-automation\ndescription: \"Automate Google Photos tasks via Rube MCP (Composio): upload media, manage albums, search photos, batch add items, create and update albums. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Photos Automation via Rube MCP\n\nUpload photos, manage albums, search media items, and batch-organize content in Google Photos using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googlephotos](https://composio.dev/toolkits/googlephotos)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googlephotos`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googlephotos`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. List Albums\nUse `GOOGLEPHOTOS_LIST_ALBUMS` to retrieve all albums visible in the user's Albums tab.\n```\nTool: GOOGLEPHOTOS_LIST_ALBUMS\nParameters:\n  - pageSize: Number of albums per page\n  - pageToken: Pagination token\n  - excludeNonAppCreatedData: Only show albums created by this app\n```\n\n### 2. Create a New Album\nUse `GOOGLEPHOTOS_CREATE_ALBUM` to create a new album in Google Photos.\n```\nTool: GOOGLEPHOTOS_CREATE_ALBUM\nParameters:\n  - title (required): Album title\n```\n\n### 3. Upload Media\nUse `GOOGLEPHOTOS_UPLOAD_MEDIA` to upload an image or video file to Google Photos.\n```\nTool: GOOGLEPHOTOS_UPLOAD_MEDIA\nParameters:\n  - file_to_upload: Local file path to upload\n  - url: URL of file to upload (alternative to file_to_upload)\n  - file_name: Name for the uploaded file\n  - description: Description/caption for the media item\n```\n\n### 4. Batch Upload and Create Media Items\nUse `GOOGLEPHOTOS_BATCH_CREATE_MEDIA_ITEMS` to upload multiple files and create media items in one operation.\n```\nTool: GOOGLEPHOTOS_BATCH_CREATE_MEDIA_ITEMS\nParameters:\n  - files: Local file paths to upload\n  - urls: URLs of files to upload\n  - media_files: Mixed input (files and URLs)\n  - albumId: Album to add items to\n  - albumPosition: Position within the album\n```\n\n### 5. Search Media Items\nUse `GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS` to search the user's photo library with filters.\n```\nTool: GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS\nParameters:\n  - albumId: Filter by album\n  - filters: Search filters (date ranges, content categories, media types)\n  - orderBy: Sort order\n  - pageSize: Results per page\n  - pageToken: Pagination token\n```\n\n### 6. Add Items to an Album\nUse `GOOGLEPHOTOS_BATCH_ADD_MEDIA_ITEMS` to add existing media items to an album.\n```\nTool: GOOGLEPHOTOS_BATCH_ADD_MEDIA_ITEMS\nParameters:\n  - albumId (required): Target album ID\n  - mediaItemIds (required): Array of media item IDs to add\n```\n\n## Common Patterns\n\n- **Create album then upload**: Use `GOOGLEPHOTOS_CREATE_ALBUM` to create an album, then `GOOGLEPHOTOS_BATCH_CREATE_MEDIA_ITEMS` with the album ID to upload and organize photos in one step.\n- **List then organize**: Use `GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS` or `GOOGLEPHOTOS_LIST_MEDIA_ITEMS` to find media item IDs, then `GOOGLEPHOTOS_BATCH_ADD_MEDIA_ITEMS` to add them to albums.\n- **Update album metadata**: Use `GOOGLEPHOTOS_UPDATE_ALBUM` to change an album's title or cover photo.\n- **Get album details**: Use `GOOGLEPHOTOS_GET_ALBUM` with an album ID to retrieve full album information.\n- **Add enrichments**: Use `GOOGLEPHOTOS_ADD_ENRICHMENT` to add text overlays, locations, or map enrichments to album positions.\n- **Upload from URLs**: Use the `url` parameter in `GOOGLEPHOTOS_UPLOAD_MEDIA` or `urls` in `GOOGLEPHOTOS_BATCH_CREATE_MEDIA_ITEMS` to upload images directly from web URLs.\n\n## Known Pitfalls\n\n- `GOOGLEPHOTOS_LIST_MEDIA_ITEMS` is **deprecated** -- prefer `GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS` for listing and filtering media.\n- `GOOGLEPHOTOS_UPLOAD_MEDIA` supports images up to **200MB** and videos up to a larger limit. Exceeding these will fail.\n- Album IDs must be obtained from `GOOGLEPHOTOS_LIST_ALBUMS` or `GOOGLEPHOTOS_CREATE_ALBUM` responses -- they are opaque strings.\n- `GOOGLEPHOTOS_BATCH_ADD_MEDIA_ITEMS` can only add items to albums **created by the app** or albums the user owns.\n- The `filters` parameter in `GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS` uses a specific Google Photos API filter structure -- consult the schema for date range and content category formats.\n- Media items created via the API may not immediately appear in the Google Photos web UI due to processing delays.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| List albums | `GOOGLEPHOTOS_LIST_ALBUMS` | `pageSize`, `pageToken` |\n| Create album | `GOOGLEPHOTOS_CREATE_ALBUM` | `title` |\n| Get album | `GOOGLEPHOTOS_GET_ALBUM` | `albumId` |\n| Update album | `GOOGLEPHOTOS_UPDATE_ALBUM` | `albumId`, `title`, `coverPhotoMediaItemId` |\n| Upload media | `GOOGLEPHOTOS_UPLOAD_MEDIA` | `file_to_upload` or `url`, `description` |\n| Batch upload | `GOOGLEPHOTOS_BATCH_CREATE_MEDIA_ITEMS` | `files` or `urls`, `albumId` |\n| Search media | `GOOGLEPHOTOS_SEARCH_MEDIA_ITEMS` | `albumId`, `filters`, `pageSize` |\n| List media items | `GOOGLEPHOTOS_LIST_MEDIA_ITEMS` | `pageSize`, `pageToken` |\n| Add items to album | `GOOGLEPHOTOS_BATCH_ADD_MEDIA_ITEMS` | `albumId`, `mediaItemIds` |\n| Add enrichment | `GOOGLEPHOTOS_ADD_ENRICHMENT` | `albumId`, `newEnrichmentItem`, `albumPosition` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googleslides-automation/SKILL.md",
    "content": "---\nname: googleslides-automation\ndescription: \"Automate Google Slides tasks via Rube MCP (Composio): create presentations, add slides from Markdown, batch update, copy from templates, get thumbnails. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Slides Automation via Rube MCP\n\nCreate, edit, and manage Google Slides presentations programmatically using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googleslides](https://composio.dev/toolkits/googleslides)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googleslides`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googleslides`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. Create a Blank Presentation\nUse `GOOGLESLIDES_PRESENTATIONS_CREATE` to initialize a new blank presentation.\n```\nTool: GOOGLESLIDES_PRESENTATIONS_CREATE\nParameters:\n  - title (required): Title for the new presentation\n  - presentationId (optional): Specific ID to assign (usually auto-generated)\n```\n\n### 2. Create Slides from Markdown\nUse `GOOGLESLIDES_CREATE_SLIDES_MARKDOWN` to generate a full presentation from Markdown text. Content is automatically split into slides.\n```\nTool: GOOGLESLIDES_CREATE_SLIDES_MARKDOWN\nParameters:\n  - title (required): Presentation title\n  - markdown_text (required): Markdown content (auto-split into slides)\n```\n\n### 3. Batch Update a Presentation\nUse `GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE` to apply updates to an existing presentation using Markdown or raw API requests.\n```\nTool: GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE\nParameters:\n  - presentationId (required): Target presentation ID\n  - markdown_text: Markdown content to update slides\n  - requests: Raw Google Slides API batch update requests\n  - writeControl: Write control settings\n```\n\n### 4. Copy from Template\nUse `GOOGLESLIDES_PRESENTATIONS_COPY_FROM_TEMPLATE` to duplicate an existing presentation as a template.\n```\nTool: GOOGLESLIDES_PRESENTATIONS_COPY_FROM_TEMPLATE\nParameters:\n  - template_presentation_id (required): Source template presentation ID\n  - new_title (required): Title for the new copy\n  - parent_folder_id (optional): Google Drive folder for the copy\n```\n\n### 5. Get Presentation Details\nUse `GOOGLESLIDES_PRESENTATIONS_GET` to retrieve the current state of a presentation including all slides and elements.\n```\nTool: GOOGLESLIDES_PRESENTATIONS_GET\nParameters:\n  - presentationId (required): Presentation ID to retrieve\n  - fields (optional): Specific fields to return\n```\n\n### 6. Generate Slide Thumbnails\nUse `GOOGLESLIDES_PRESENTATIONS_PAGES_GET_THUMBNAIL` to generate a thumbnail image URL for a specific slide.\n```\nTool: GOOGLESLIDES_PRESENTATIONS_PAGES_GET_THUMBNAIL\nParameters:\n  - presentationId (required): Presentation ID\n  - pageObjectId (required): Page/slide object ID\n  - thumbnailProperties.mimeType: Image format (e.g., PNG)\n  - thumbnailProperties.thumbnailSize: Thumbnail size\n```\n\n## Common Patterns\n\n- **Markdown-first workflow**: Use `GOOGLESLIDES_CREATE_SLIDES_MARKDOWN` to quickly generate presentations from structured text. The tool auto-splits content into separate slides.\n- **Template-based generation**: Use `GOOGLESLIDES_PRESENTATIONS_COPY_FROM_TEMPLATE` to copy a styled template, then `GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE` to fill in content.\n- **Retrieve then modify**: Use `GOOGLESLIDES_PRESENTATIONS_GET` to inspect slide structure and object IDs, then `GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE` to make targeted changes.\n- **Export thumbnails**: Use `GOOGLESLIDES_PRESENTATIONS_PAGES_GET` to list page object IDs, then `GOOGLESLIDES_PRESENTATIONS_PAGES_GET_THUMBNAIL` to generate preview images.\n- **Share presentations**: Combine with `GOOGLEDRIVE_ADD_FILE_SHARING_PREFERENCE` (googledrive toolkit) to share after creation.\n\n## Known Pitfalls\n\n- `GOOGLESLIDES_CREATE_SLIDES_MARKDOWN` creates a brand-new presentation each time -- it cannot append to an existing one.\n- `GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE` with raw `requests` requires knowledge of the Google Slides API request format. Prefer `markdown_text` for simpler updates.\n- Page object IDs must be obtained from `GOOGLESLIDES_PRESENTATIONS_GET` before using thumbnail or page-get tools.\n- The `presentationId` is the long alphanumeric string from the Google Slides URL (between `/d/` and `/edit`).\n- Copying from a template requires the authenticated user to have at least read access to the template presentation.\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| Create blank presentation | `GOOGLESLIDES_PRESENTATIONS_CREATE` | `title` |\n| Create from Markdown | `GOOGLESLIDES_CREATE_SLIDES_MARKDOWN` | `title`, `markdown_text` |\n| Batch update slides | `GOOGLESLIDES_PRESENTATIONS_BATCH_UPDATE` | `presentationId`, `markdown_text` or `requests` |\n| Copy from template | `GOOGLESLIDES_PRESENTATIONS_COPY_FROM_TEMPLATE` | `template_presentation_id`, `new_title` |\n| Get presentation | `GOOGLESLIDES_PRESENTATIONS_GET` | `presentationId` |\n| Get page details | `GOOGLESLIDES_PRESENTATIONS_PAGES_GET` | `presentationId`, `pageObjectId` |\n| Get slide thumbnail | `GOOGLESLIDES_PRESENTATIONS_PAGES_GET_THUMBNAIL` | `presentationId`, `pageObjectId` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googlesuper-automation/SKILL.md",
    "content": "---\nname: googlesuper-automation\ndescription: \"Automate Google Super tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Super Automation via Rube MCP\n\nAutomate Google Super operations through Composio's Google Super toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/googlesuper](https://composio.dev/toolkits/googlesuper)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Google Super connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googlesuper`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googlesuper`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Google Super operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Google Super task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"googlesuper\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Google Super-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `googlesuper` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/googletasks-automation/SKILL.md",
    "content": "---\nname: googletasks-automation\ndescription: \"Automate Google Tasks via Rube MCP (Composio): create, list, update, delete, move, and bulk-insert tasks and task lists. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Google Tasks Automation via Rube MCP\n\nCreate, manage, organize, and bulk-operate on Google Tasks and task lists using Rube MCP (Composio).\n\n**Toolkit docs**: [composio.dev/toolkits/googletasks](https://composio.dev/toolkits/googletasks)\n\n## Prerequisites\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `googletasks`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `googletasks`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Core Workflows\n\n### 1. List All Task Lists\nUse `GOOGLETASKS_LIST_TASK_LISTS` to fetch all available task lists for the authenticated user.\n```\nTool: GOOGLETASKS_LIST_TASK_LISTS\nParameters:\n  - maxResults: Maximum task lists to return\n  - pageToken: Pagination token for next page\n```\n\n### 2. Create a New Task\nUse `GOOGLETASKS_INSERT_TASK` to add a new task to a specific task list.\n```\nTool: GOOGLETASKS_INSERT_TASK\nParameters:\n  - tasklist_id (required): ID of the target task list\n  - title (required): Task title\n  - notes: Task description/notes\n  - due: Due date in RFC3339 format (e.g., \"2025-01-20T00:00:00.000Z\")\n  - status: \"needsAction\" or \"completed\"\n  - task_parent: Parent task ID (to create subtask)\n  - task_previous: Previous task ID (for ordering)\n```\n\n### 3. List All Tasks Across Lists\nUse `GOOGLETASKS_LIST_ALL_TASKS` to fetch tasks across all task lists with optional filters.\n```\nTool: GOOGLETASKS_LIST_ALL_TASKS\nParameters:\n  - max_tasks_total: Maximum total tasks to return\n  - showCompleted: Include completed tasks\n  - showDeleted: Include deleted tasks\n  - showHidden: Include hidden tasks\n  - dueMin / dueMax: Filter by due date range\n  - completedMin / completedMax: Filter by completion date\n  - updatedMin: Filter by last update time\n  - showAssigned: Include assigned tasks\n```\n\n### 4. Update an Existing Task\nUse `GOOGLETASKS_UPDATE_TASK` to modify a task's title, notes, due date, or status.\n```\nTool: GOOGLETASKS_UPDATE_TASK\nParameters:\n  - tasklist_id (required): Task list ID\n  - task_id (required): Task ID to update\n  - title: New title\n  - notes: Updated notes\n  - due: New due date (RFC3339)\n  - status: \"needsAction\" or \"completed\"\n```\n\n### 5. Bulk Insert Tasks\nUse `GOOGLETASKS_BULK_INSERT_TASKS` to create multiple tasks at once in a single operation.\n```\nTool: GOOGLETASKS_BULK_INSERT_TASKS\nParameters:\n  - tasklist_id (required): Target task list ID\n  - tasks (required): Array of task objects (each with title, notes, due, status)\n  - batch_size: Number of tasks per batch request\n```\n\n### 6. Delete or Clear Tasks\nUse `GOOGLETASKS_DELETE_TASK` to remove a specific task, or `GOOGLETASKS_CLEAR_TASKS` to permanently remove all completed tasks from a list.\n```\nTool: GOOGLETASKS_DELETE_TASK\nParameters:\n  - tasklist_id (required): Task list ID\n  - task_id (required): Task ID to delete\n\nTool: GOOGLETASKS_CLEAR_TASKS\nParameters:\n  - tasklist (required): Task list ID to clear completed tasks from\n```\n\n## Common Patterns\n\n- **Get task list ID first**: Always start with `GOOGLETASKS_LIST_TASK_LISTS` to discover available task lists and their IDs before creating or listing tasks.\n- **List then update**: Use `GOOGLETASKS_LIST_ALL_TASKS` or `GOOGLETASKS_LIST_TASKS` to find task IDs, then use `GOOGLETASKS_UPDATE_TASK` to modify them.\n- **Mark complete**: Update a task with `status: \"completed\"` using `GOOGLETASKS_UPDATE_TASK`.\n- **Create subtasks**: Use `GOOGLETASKS_INSERT_TASK` with the `task_parent` parameter set to the parent task's ID.\n- **Reorder tasks**: Use `GOOGLETASKS_MOVE_TASK` to change a task's position within its list or reparent it.\n- **Batch creation**: Use `GOOGLETASKS_BULK_INSERT_TASKS` for creating many tasks at once (e.g., importing from another system).\n\n## Known Pitfalls\n\n- Both `tasklist_id` and `task_id` are **required** for `GOOGLETASKS_UPDATE_TASK`, `GOOGLETASKS_DELETE_TASK`, and `GOOGLETASKS_GET_TASK`. You cannot operate on a task without knowing which list it belongs to.\n- All date/time strings must be in **RFC3339 format** (e.g., `2025-01-20T00:00:00.000Z`). Other formats will be rejected.\n- `GOOGLETASKS_CLEAR_TASKS` permanently deletes all **completed** tasks from a list. This action is irreversible.\n- `GOOGLETASKS_LIST_ALL_TASKS` fetches across all lists but results may be paginated -- check for pagination tokens.\n- Task list IDs are not the same as task list names. Always resolve names to IDs using `GOOGLETASKS_LIST_TASK_LISTS`.\n- The default task list is typically named \"My Tasks\" but its ID is an opaque string, not \"default\" or \"primary\".\n\n## Quick Reference\n| Action | Tool | Key Parameters |\n|--------|------|----------------|\n| List task lists | `GOOGLETASKS_LIST_TASK_LISTS` | `maxResults`, `pageToken` |\n| List all tasks | `GOOGLETASKS_LIST_ALL_TASKS` | `max_tasks_total`, `showCompleted`, `dueMin` |\n| List tasks in a list | `GOOGLETASKS_LIST_TASKS` | `tasklist_id`, `maxResults`, `showCompleted` |\n| Get single task | `GOOGLETASKS_GET_TASK` | `tasklist_id`, `task_id` |\n| Create task | `GOOGLETASKS_INSERT_TASK` | `tasklist_id`, `title`, `notes`, `due` |\n| Bulk create tasks | `GOOGLETASKS_BULK_INSERT_TASKS` | `tasklist_id`, `tasks` |\n| Update task | `GOOGLETASKS_UPDATE_TASK` | `tasklist_id`, `task_id`, `title`, `status` |\n| Delete task | `GOOGLETASKS_DELETE_TASK` | `tasklist_id`, `task_id` |\n| Move/reorder task | `GOOGLETASKS_MOVE_TASK` | `tasklist_id`, `task_id` |\n| Clear completed | `GOOGLETASKS_CLEAR_TASKS` | `tasklist` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gorgias-automation/SKILL.md",
    "content": "---\nname: Gorgias Automation\ndescription: \"Automate e-commerce customer support workflows in Gorgias -- manage tickets, customers, tags, and teams through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Gorgias Automation\n\nAutomate your Gorgias helpdesk operations directly from Claude Code. Create, update, and triage support tickets, manage customers, and organize your support team -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/gorgias](https://composio.dev/toolkits/gorgias)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Gorgias account through the connection link provided\n3. Start automating your support workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. List and Filter Tickets\n\nRetrieve tickets with filtering by status, channel, assignee, date range, and more.\n\n**Tool:** `GORGIAS_LIST_TICKETS`\n\n```\nList all open tickets from the email channel created in the last 7 days\n```\n\nKey parameters:\n- `status` -- filter by ticket status (e.g., \"open\", \"closed\")\n- `channel` -- filter by channel (e.g., \"email\", \"chat\")\n- `assignee_user_id` / `assignee_team_id` -- filter by assigned agent or team\n- `created_from` / `created_to` -- ISO date range filters\n- `limit` (max 100) / `offset` -- pagination controls\n- `order_by` / `order_dir` -- sorting options\n\n### 2. Create and Update Tickets\n\nCreate new tickets or update existing ones with assignment, priority, and status changes.\n\n**Tools:** `GORGIAS_CREATE_TICKET`, `GORGIAS_UPDATE_TICKET`, `GORGIAS_GET_TICKET`\n\n```\nCreate a high-priority ticket for customer 12345 about a missing order with subject \"Order #9876 not delivered\"\n```\n\n- `GORGIAS_CREATE_TICKET` requires `customer_id`; accepts `subject`, `status`, `priority`, `channel`, `messages`, `tags`\n- `GORGIAS_UPDATE_TICKET` requires `ticket_id`; all other fields are optional partial updates\n- `GORGIAS_GET_TICKET` retrieves full ticket details by `ticket_id`\n\n### 3. Manage Ticket Tags\n\nAdd tags to tickets for categorization, routing, and reporting.\n\n**Tools:** `GORGIAS_ADD_TICKET_TAGS`, `GORGIAS_LIST_TICKET_TAGS`\n\n```\nAdd tags 101 and 202 to ticket 5678, then show me all tags on that ticket\n```\n\n- `GORGIAS_ADD_TICKET_TAGS` requires `ticket_id` and `tag_ids` (array of integers)\n- `GORGIAS_LIST_TICKET_TAGS` requires `ticket_id` to retrieve current tags\n\n### 4. Customer Management\n\nCreate new customers or merge duplicate customer records.\n\n**Tools:** `GORGIAS_CREATE_CUSTOMER`, `GORGIAS_MERGE_CUSTOMERS`, `GORGIAS_LIST_CUSTOMERS`\n\n```\nCreate a new customer named \"Jane Doe\" with email jane@example.com and phone channel\n```\n\n- `GORGIAS_CREATE_CUSTOMER` requires `name`; accepts `email`, `channels` (array with `type` and `value`), `external_id`, `address`, `data`\n- `GORGIAS_MERGE_CUSTOMERS` requires `source_customer_id` and `target_customer_id` -- source is merged into target\n- `GORGIAS_LIST_CUSTOMERS` retrieves customers with filtering options\n\n### 5. Team and Account Operations\n\nList teams, retrieve account info, and inspect ticket custom fields.\n\n**Tools:** `GORGIAS_LIST_TEAMS`, `GORGIAS_GET_TEAM`, `GORGIAS_GET_ACCOUNT`, `GORGIAS_LIST_TICKET_FIELD_VALUES`\n\n```\nShow me all support teams in our Gorgias account\n```\n\n- `GORGIAS_GET_ACCOUNT` returns account-level metrics and configuration\n- `GORGIAS_LIST_TEAMS` / `GORGIAS_GET_TEAM` manage team lookup\n- `GORGIAS_LIST_TICKET_FIELD_VALUES` returns custom field values for a given ticket\n\n### 6. Activity and Event Tracking\n\nMonitor ticket activity and customer event history.\n\n**Tools:** `GORGIAS_LIST_EVENTS`\n\n```\nList recent events to see what activity has happened across our support queue\n```\n\n- `GORGIAS_LIST_EVENTS` provides an activity timeline with filtering options\n\n---\n\n## Known Pitfalls\n\n- **Pagination required:** `GORGIAS_LIST_TICKETS` uses `limit`/`offset` pagination. Failing to loop through pages will miss older tickets and produce incomplete data.\n- **Filter specificity:** Missing or overly broad filters on `GORGIAS_LIST_TICKETS` can overload the export or omit the desired reporting window. Always set `created_from`/`created_to` for time-bound queries.\n- **Custom fields are separate:** Key business KPIs may only exist in custom fields. You must query `GORGIAS_LIST_TICKET_FIELD_VALUES` explicitly to include them.\n- **Rate limits:** High-volume exports across `GORGIAS_LIST_TICKETS` and related endpoints can hit Gorgias rate limits. Add backoff and resume from the last offset.\n- **Auth errors:** 401/403 responses on any Gorgias tool indicate token or permission issues. Do not treat partial data as a complete dataset.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `GORGIAS_LIST_TICKETS` | List tickets with filters (status, channel, date, assignee) |\n| `GORGIAS_GET_TICKET` | Retrieve a specific ticket by ID |\n| `GORGIAS_CREATE_TICKET` | Create a new ticket (requires `customer_id`) |\n| `GORGIAS_UPDATE_TICKET` | Update ticket fields (requires `ticket_id`) |\n| `GORGIAS_ADD_TICKET_TAGS` | Add tags to a ticket |\n| `GORGIAS_LIST_TICKET_TAGS` | List all tags on a ticket |\n| `GORGIAS_LIST_TICKET_FIELD_VALUES` | List custom field values for a ticket |\n| `GORGIAS_CREATE_CUSTOMER` | Create a new customer (requires `name`) |\n| `GORGIAS_MERGE_CUSTOMERS` | Merge two customer records |\n| `GORGIAS_LIST_CUSTOMERS` | List customers with filters |\n| `GORGIAS_LIST_TEAMS` | List all teams |\n| `GORGIAS_GET_TEAM` | Retrieve a specific team |\n| `GORGIAS_GET_ACCOUNT` | Retrieve account information |\n| `GORGIAS_LIST_EVENTS` | List activity events with filters |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gosquared-automation/SKILL.md",
    "content": "---\nname: gosquared-automation\ndescription: \"Automate Gosquared tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Gosquared Automation via Rube MCP\n\nAutomate Gosquared operations through Composio's Gosquared toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/gosquared](https://composio.dev/toolkits/gosquared)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Gosquared connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `gosquared`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `gosquared`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Gosquared operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Gosquared task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"gosquared\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Gosquared-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `gosquared` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/grafbase-automation/SKILL.md",
    "content": "---\nname: grafbase-automation\ndescription: \"Automate Grafbase tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Grafbase Automation via Rube MCP\n\nAutomate Grafbase operations through Composio's Grafbase toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/grafbase](https://composio.dev/toolkits/grafbase)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Grafbase connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `grafbase`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `grafbase`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Grafbase operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Grafbase task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"grafbase\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Grafbase-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `grafbase` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/graphhopper-automation/SKILL.md",
    "content": "---\nname: graphhopper-automation\ndescription: \"Automate Graphhopper tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Graphhopper Automation via Rube MCP\n\nAutomate Graphhopper operations through Composio's Graphhopper toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/graphhopper](https://composio.dev/toolkits/graphhopper)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Graphhopper connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `graphhopper`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `graphhopper`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Graphhopper operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Graphhopper task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"graphhopper\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Graphhopper-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `graphhopper` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/griptape-automation/SKILL.md",
    "content": "---\nname: griptape-automation\ndescription: \"Automate Griptape tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Griptape Automation via Rube MCP\n\nAutomate Griptape operations through Composio's Griptape toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/griptape](https://composio.dev/toolkits/griptape)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Griptape connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `griptape`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `griptape`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Griptape operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Griptape task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"griptape\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Griptape-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `griptape` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/grist-automation/SKILL.md",
    "content": "---\nname: grist-automation\ndescription: \"Automate Grist tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Grist Automation via Rube MCP\n\nAutomate Grist operations through Composio's Grist toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/grist](https://composio.dev/toolkits/grist)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Grist connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `grist`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `grist`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Grist operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Grist task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"grist\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Grist-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `grist` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/groqcloud-automation/SKILL.md",
    "content": "---\nname: GroqCloud Automation\ndescription: \"Automate AI inference, chat completions, audio translation, and TTS voice management through GroqCloud's high-performance API via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# GroqCloud Automation\n\nAutomate AI inference workflows using GroqCloud's ultra-fast API -- chat completions, model discovery, audio translation, and TTS voice selection -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/groqcloud](https://composio.dev/toolkits/groqcloud)\n\n---\n\n## Setup\n\n1. Connect your GroqCloud account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `GROQCLOUD_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. Discover Available Models\nList all models available on GroqCloud to find valid model IDs before running inference.\n\n**Tool:** `GROQCLOUD_LIST_MODELS`\n\n```\nNo parameters required -- returns all available models with metadata.\n```\n\nUse this as a prerequisite before any chat completion call to ensure you reference a valid, non-deprecated model ID.\n\n---\n\n### 2. Run Chat Completions\nGenerate AI responses for conversational prompts using a specified GroqCloud model.\n\n**Tool:** `GROQCLOUD_GROQ_CREATE_CHAT_COMPLETION`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `model` | string | Yes | Model ID from `GROQCLOUD_LIST_MODELS` |\n| `messages` | array | Yes | Ordered list of `{role, content}` objects (`system`, `user`, `assistant`) |\n| `temperature` | number | No | Sampling temperature 0-2 (default: 1) |\n| `max_completion_tokens` | integer | No | Max tokens to generate |\n| `top_p` | number | No | Nucleus sampling 0-1 (default: 1) |\n| `stop` | string/array | No | Up to 4 stop sequences |\n| `stream` | boolean | No | Enable SSE streaming (default: false) |\n\n---\n\n### 3. Inspect Model Details\nRetrieve detailed metadata for a specific model including context window and capabilities.\n\n**Tool:** `GROQCLOUD_GROQ_RETRIEVE_MODEL`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `model` | string | Yes | Model identifier (e.g., `groq-1-large`) |\n\n---\n\n### 4. Translate Audio to English\nTranslate non-English audio files into English text using Whisper models.\n\n**Tool:** `GROQCLOUD_GROQ_CREATE_AUDIO_TRANSLATION`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `file_path` | string | Yes | Local path, HTTP(S) URL, or base64 data URL for audio |\n| `model` | string | No | Model ID (default: `whisper-large-v3`). Note: `whisper-large-v3-turbo` may not support translations |\n| `response_format` | string | No | `json`, `verbose_json`, or `text` (default: `json`) |\n| `temperature` | number | No | Sampling temperature 0-1 (default: 0) |\n\n---\n\n### 5. List TTS Voices\nEnumerate available text-to-speech voices for Groq PlayAI models to drive voice selection UX.\n\n**Tool:** `GROQCLOUD_LIST_VOICES`\n\n```\nReturns the set of supported TTS voices. Note: this is a static list maintained manually.\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Nested model list** | `GROQCLOUD_LIST_MODELS` response may be nested at `response['data']['data']` -- do not assume a flat top-level array |\n| **Hard-coded model IDs break** | Always fetch model IDs dynamically via `GROQCLOUD_LIST_MODELS`; hard-coded names can break when models are deprecated or renamed |\n| **Audio format validation** | `GROQCLOUD_GROQ_CREATE_AUDIO_TRANSLATION` rejects invalid or unsupported audio formats silently -- validate inputs before calling |\n| **Model metadata drifts** | Data from `GROQCLOUD_GROQ_RETRIEVE_MODEL` (context window, features) can change as models update -- do not treat it as static |\n| **TTS voice changes** | Voice sets from `GROQCLOUD_LIST_VOICES` may shrink or rename over time -- handle missing voices gracefully |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `GROQCLOUD_LIST_MODELS` | List all available models and metadata |\n| `GROQCLOUD_GROQ_CREATE_CHAT_COMPLETION` | Generate chat-based AI completions |\n| `GROQCLOUD_GROQ_RETRIEVE_MODEL` | Get detailed info for a specific model |\n| `GROQCLOUD_GROQ_CREATE_AUDIO_TRANSLATION` | Translate non-English audio to English text |\n| `GROQCLOUD_LIST_VOICES` | Retrieve available TTS voices for PlayAI |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/gumroad-automation/SKILL.md",
    "content": "---\nname: Gumroad Automation\ndescription: \"Automate Gumroad product management, sales tracking, license verification, and webhook subscriptions using natural language through the Composio MCP integration.\"\ncategory: e-commerce\nrequires:\n  mcp:\n    - rube\n---\n\n# Gumroad Automation\n\nAutomate your Gumroad storefront -- list products, track sales, verify licenses, and manage real-time webhooks -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/gumroad](https://composio.dev/toolkits/gumroad)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Gumroad account when prompted (API key authentication).\n3. Start issuing natural language commands to manage your Gumroad store.\n\n---\n\n## Core Workflows\n\n### 1. List All Products\nRetrieve every product in your authenticated Gumroad account to get product IDs for downstream operations.\n\n**Tool:** `GUMROAD_LIST_PRODUCTS`\n\n**Example prompt:**\n> \"List all my Gumroad products\"\n\n**Parameters:** None required -- returns all products for the authenticated account.\n\n---\n\n### 2. Track Sales with Filters\nRetrieve successful sales with optional filtering by email, date range, product, or pagination.\n\n**Tool:** `GUMROAD_GET_SALES`\n\n**Example prompt:**\n> \"Show me all Gumroad sales from January 2025 for product prod_ABC123\"\n\n**Key parameters:**\n- `after` -- ISO8601 date/time to filter sales after (e.g., `2025-01-01T00:00:00Z`)\n- `before` -- ISO8601 date/time to filter sales before\n- `email` -- Filter by customer email address\n- `product_id` -- Filter by specific product ID\n- `page` -- Page number for paginated results (minimum 1)\n\n---\n\n### 3. Verify License Keys\nCheck if a license key is valid against a specific product, inspect usage count, or verify membership entitlement.\n\n**Tool:** `GUMROAD_VERIFY_LICENSE`\n\n**Example prompt:**\n> \"Verify license key ABCD-EFGH-IJKL-MNOP for product prod_ABC123\"\n\n**Key parameters (all required):**\n- `product_id` -- The product ID to verify against (required for products created on/after Jan 9, 2023)\n- `license_key` -- The license key string (e.g., `ABCD-EFGH-IJKL-MNOP`)\n- `increment_uses_count` -- Whether to increment usage count (defaults to true)\n\n---\n\n### 4. Subscribe to Webhook Events\nSet up real-time event notifications by subscribing your endpoint URL to specific Gumroad resource events.\n\n**Tool:** `GUMROAD_SUBSCRIBE_TO_RESOURCE`\n\n**Example prompt:**\n> \"Subscribe my webhook https://example.com/hook to Gumroad sale events\"\n\n**Key parameters (all required):**\n- `resource_name` -- One of: `sale`, `refund`, `dispute`, `dispute_won`, `cancellation`, `subscription_updated`, `subscription_ended`, `subscription_restarted`\n- `post_url` -- Your endpoint URL that receives HTTP POST notifications\n\n---\n\n### 5. List Active Webhook Subscriptions\nReview existing webhook subscriptions for a given resource type before adding new ones to avoid duplicates.\n\n**Tool:** `GUMROAD_GET_RESOURCE_SUBSCRIPTIONS`\n\n**Example prompt:**\n> \"Show all my active Gumroad webhook subscriptions for sale events\"\n\n**Key parameters (required):**\n- `resource_name` -- One of the eight supported event types (e.g., `sale`, `refund`)\n\n---\n\n## Known Pitfalls\n\n- **Product ID required for license verification**: Products created on or after January 9, 2023 require the `product_id` parameter. Older products may work without it but providing it is recommended.\n- **Pagination on sales**: Sales results are paginated. Always check if more pages exist by incrementing the `page` parameter.\n- **Webhook deduplication**: Before subscribing to a resource, use `GUMROAD_GET_RESOURCE_SUBSCRIPTIONS` to check for existing subscriptions and avoid duplicate webhooks.\n- **ISO8601 date format**: Date filters on sales must use ISO8601 format (e.g., `2025-01-01T00:00:00Z`), not plain dates.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| List products | `GUMROAD_LIST_PRODUCTS` | None |\n| Get sales | `GUMROAD_GET_SALES` | None (all optional filters) |\n| Verify license | `GUMROAD_VERIFY_LICENSE` | `product_id`, `license_key` |\n| Subscribe to events | `GUMROAD_SUBSCRIBE_TO_RESOURCE` | `resource_name`, `post_url` |\n| List webhook subs | `GUMROAD_GET_RESOURCE_SUBSCRIPTIONS` | `resource_name` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/habitica-automation/SKILL.md",
    "content": "---\nname: habitica-automation\ndescription: \"Automate Habitica tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Habitica Automation via Rube MCP\n\nAutomate Habitica operations through Composio's Habitica toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/habitica](https://composio.dev/toolkits/habitica)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Habitica connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `habitica`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `habitica`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Habitica operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Habitica task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"habitica\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Habitica-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `habitica` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hackernews-automation/SKILL.md",
    "content": "---\nname: hackernews-automation\ndescription: \"Automate Hackernews tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hackernews Automation via Rube MCP\n\nAutomate Hackernews operations through Composio's Hackernews toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hackernews](https://composio.dev/toolkits/hackernews)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hackernews connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hackernews`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hackernews`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hackernews operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hackernews task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hackernews\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hackernews-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hackernews` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/happy-scribe-automation/SKILL.md",
    "content": "---\nname: happy-scribe-automation\ndescription: \"Automate Happy Scribe tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Happy Scribe Automation via Rube MCP\n\nAutomate Happy Scribe operations through Composio's Happy Scribe toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/happy_scribe](https://composio.dev/toolkits/happy_scribe)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Happy Scribe connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `happy_scribe`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `happy_scribe`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Happy Scribe operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Happy Scribe task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"happy_scribe\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Happy Scribe-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `happy_scribe` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/harvest-automation/SKILL.md",
    "content": "---\nname: Harvest Automation\ndescription: \"Automate time tracking, project management, and invoicing workflows in Harvest -- log hours, manage projects, clients, and tasks through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Harvest Automation\n\nAutomate your Harvest time tracking operations directly from Claude Code. Log time entries, manage projects and clients, create tasks, and pull reporting data -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/harvest](https://composio.dev/toolkits/harvest)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Harvest account through the connection link provided\n3. Start automating your time tracking workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Log and Manage Time Entries\n\nCreate, list, update, and retrieve time entries for accurate billing and reporting.\n\n**Tools:** `HARVEST_CREATE_TIME_ENTRY`, `HARVEST_LIST_TIME_ENTRIES`, `HARVEST_GET_TIME_ENTRY`, `HARVEST_UPDATE_TIME_ENTRY`\n\n```\nLog 3.5 hours of development work on project 12345, task 67890 for today\n```\n\nKey parameters for `HARVEST_CREATE_TIME_ENTRY`:\n- `project_id` (required) -- the project to log against\n- `task_id` (required) -- the task must be assigned to the project\n- `spent_date` (required) -- date in YYYY-MM-DD format\n- `hours` -- total hours (for duration-based accounts)\n- `started_time` / `ended_time` -- for timestamp-based accounts\n- `notes` -- description of work performed\n\nKey parameters for `HARVEST_LIST_TIME_ENTRIES`:\n- `from_date` / `to` -- date range filters (YYYY-MM-DD)\n- `project_id`, `client_id`, `task_id`, `user_id` -- entity filters\n- `is_billed` / `is_running` -- status filters\n- `page` / `per_page` (max 2000) -- pagination\n\n### 2. Manage Projects\n\nCreate new projects and list existing ones with client and billing configuration.\n\n**Tools:** `HARVEST_CREATE_PROJECT`, `HARVEST_LIST_PROJECTS`, `HARVEST_GET_PROJECT`\n\n```\nCreate a billable project called \"Website Redesign\" for client 456 with Tasks billing and project budget\n```\n\nKey parameters for `HARVEST_CREATE_PROJECT`:\n- `name`, `client_id`, `is_billable`, `bill_by`, `budget_by` (all required)\n- `bill_by` options: `\"Project\"`, `\"Tasks\"`, `\"People\"`, `\"none\"`\n- `budget_by` options: `\"project\"`, `\"project_cost\"`, `\"task\"`, `\"task_fees\"`, `\"person\"`, `\"none\"`\n- Optional: `budget`, `hourly_rate`, `starts_on`, `ends_on`, `is_fixed_fee`\n\n### 3. Manage Clients\n\nCreate and list clients that projects are organized under.\n\n**Tools:** `HARVEST_CREATE_CLIENT`, `HARVEST_LIST_CLIENTS`\n\n```\nList all active clients in our Harvest account\n```\n\n- `HARVEST_CREATE_CLIENT` requires `name`; accepts `address`, `currency`, `is_active`\n- `HARVEST_LIST_CLIENTS` supports `is_active` filter and pagination (`per_page` max 2000)\n\n### 4. Manage Tasks\n\nCreate and list reusable task types for time tracking.\n\n**Tools:** `HARVEST_CREATE_TASK`, `HARVEST_LIST_TASKS`\n\n```\nCreate a new billable task called \"Code Review\" with a default rate of $150/hr\n```\n\n- `HARVEST_CREATE_TASK` requires `name`; accepts `billable_by_default`, `default_hourly_rate`, `is_active`, `is_default`\n- `HARVEST_LIST_TASKS` supports `is_active`, `is_default` filters and pagination (`per_page` max 100)\n- Task names must be unique across all tasks (active and archived)\n\n### 5. Time Entry Reporting\n\nPull time entries with date ranges and filters for billing summaries and utilization reports.\n\n**Tools:** `HARVEST_LIST_TIME_ENTRIES`, `HARVEST_GET_TIME_ENTRY`\n\n```\nShow me all unbilled time entries for project 789 from January 2026\n```\n\n- Use `from_date` and `to` for date windowing\n- Filter with `is_billed: false` for unbilled entries\n- Combine `project_id`, `user_id`, `client_id` for cross-dimensional reporting\n- Paginate with `page` and `per_page` to gather complete datasets\n\n### 6. Update and Correct Time Entries\n\nModify existing time entries to fix hours, reassign projects, or update notes.\n\n**Tools:** `HARVEST_UPDATE_TIME_ENTRY`\n\n```\nUpdate time entry 123456 to change the hours to 4.0 and add the note \"Completed API integration\"\n```\n\n- Requires `time_entry_id`\n- Supports partial updates -- only include fields you want to change\n- Can update `hours`, `notes`, `project_id`, `task_id`, `spent_date`, `started_time`, `ended_time`\n\n---\n\n## Known Pitfalls\n\n- **Task assignment matters:** When creating time entries, the `task_id` must correspond to a task that is actually assigned to the specified `project_id`. Use project task assignments endpoint to verify, not just `HARVEST_LIST_TASKS` (which returns global tasks).\n- **Duration vs. timestamp tracking:** Harvest accounts are configured for either duration-based or timestamp-based tracking. `hours` is ignored on timestamp accounts; `started_time`/`ended_time` are ignored on duration accounts.\n- **Pagination limits vary:** `HARVEST_LIST_TIME_ENTRIES` and `HARVEST_LIST_CLIENTS` support up to 2000 per page, but `HARVEST_LIST_PROJECTS` and `HARVEST_LIST_TASKS` cap at 100 per page.\n- **Date format consistency:** All date parameters must use `YYYY-MM-DD` format. ISO 8601 with timezone is used for `updated_since` filters.\n- **Required fields for projects:** `HARVEST_CREATE_PROJECT` requires five fields: `name`, `client_id`, `is_billable`, `bill_by`, and `budget_by`. Missing any will cause a validation error.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `HARVEST_LIST_TIME_ENTRIES` | List time entries with date, project, client, user filters |\n| `HARVEST_CREATE_TIME_ENTRY` | Log a new time entry (requires `project_id`, `task_id`, `spent_date`) |\n| `HARVEST_GET_TIME_ENTRY` | Retrieve a specific time entry by ID |\n| `HARVEST_UPDATE_TIME_ENTRY` | Update an existing time entry (requires `time_entry_id`) |\n| `HARVEST_LIST_PROJECTS` | List projects with optional client filter |\n| `HARVEST_CREATE_PROJECT` | Create a new project with billing config |\n| `HARVEST_GET_PROJECT` | Retrieve a specific project by ID |\n| `HARVEST_LIST_CLIENTS` | List clients with active/inactive filter |\n| `HARVEST_CREATE_CLIENT` | Create a new client (requires `name`) |\n| `HARVEST_LIST_TASKS` | List reusable task types |\n| `HARVEST_CREATE_TASK` | Create a new task type (requires `name`) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hashnode-automation/SKILL.md",
    "content": "---\nname: hashnode-automation\ndescription: \"Automate Hashnode tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hashnode Automation via Rube MCP\n\nAutomate Hashnode operations through Composio's Hashnode toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hashnode](https://composio.dev/toolkits/hashnode)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hashnode connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hashnode`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hashnode`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hashnode operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hashnode task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hashnode\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hashnode-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hashnode` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/helcim-automation/SKILL.md",
    "content": "---\nname: helcim-automation\ndescription: \"Automate Helcim tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Helcim Automation via Rube MCP\n\nAutomate Helcim operations through Composio's Helcim toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/helcim](https://composio.dev/toolkits/helcim)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Helcim connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `helcim`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `helcim`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Helcim operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Helcim task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"helcim\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Helcim-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `helcim` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/helloleads-automation/SKILL.md",
    "content": "---\nname: helloleads-automation\ndescription: \"Automate Helloleads tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Helloleads Automation via Rube MCP\n\nAutomate Helloleads operations through Composio's Helloleads toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/helloleads](https://composio.dev/toolkits/helloleads)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Helloleads connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `helloleads`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `helloleads`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Helloleads operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Helloleads task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"helloleads\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Helloleads-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `helloleads` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/helpwise-automation/SKILL.md",
    "content": "---\nname: helpwise-automation\ndescription: \"Automate Helpwise tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Helpwise Automation via Rube MCP\n\nAutomate Helpwise operations through Composio's Helpwise toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/helpwise](https://composio.dev/toolkits/helpwise)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Helpwise connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `helpwise`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `helpwise`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Helpwise operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Helpwise task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"helpwise\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Helpwise-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `helpwise` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/here-automation/SKILL.md",
    "content": "---\nname: here-automation\ndescription: \"Automate Here tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Here Automation via Rube MCP\n\nAutomate Here operations through Composio's Here toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/here](https://composio.dev/toolkits/here)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Here connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `here`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `here`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Here operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Here task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"here\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Here-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `here` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/heygen-automation/SKILL.md",
    "content": "---\nname: HeyGen Automation\ndescription: \"Automate AI video generation, avatar browsing, template-based video creation, and video status tracking through HeyGen's platform via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# HeyGen Automation\n\nAutomate AI-powered video creation workflows -- browse avatars and templates, generate personalized videos from templates, track processing status, and retrieve shareable URLs -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/heygen](https://composio.dev/toolkits/heygen)\n\n---\n\n## Setup\n\n1. Connect your HeyGen account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `HEYGEN_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. Browse Available Templates\nRetrieve pre-designed avatar templates from the HeyGen library for video creation.\n\n**Tool:** `HEYGEN_V2_TEMPLATES`\n\n```\nNo parameters required -- returns template IDs, names, preview images, and customization options.\n```\n\nUse this to discover templates before generating videos. Each template has a unique ID needed for generation.\n\n---\n\n### 2. Inspect Template Details & Variables\nRetrieve the full structure of a template including all variables, scene mappings, and customization options.\n\n**Tool:** `HEYGEN_RETRIEVE_TEMPLATE_DETAILS_V3`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `template_id` | string | Yes | Template ID from `HEYGEN_V2_TEMPLATES` or the HeyGen dashboard |\n\nThis is a **required prerequisite** before generating videos -- it tells you exactly which variables must be populated.\n\n---\n\n### 3. Browse Available Avatars\nList all realistic avatars available for video creation, useful for mapping characters to scenes.\n\n**Tool:** `HEYGEN_V2_AVATARS`\n\n```\nNo parameters required -- returns avatar identifiers, names, and preview images.\nThe list may be paginated; additional calls might be needed for the full set.\n```\n\n---\n\n### 4. Generate Video from Template\nCreate a customized video by populating a template with your variables and content.\n\n**Tool:** `HEYGEN_V2_TEMPLATE_GENERATE`\n\nProvide a video title and all template variables discovered via `HEYGEN_RETRIEVE_TEMPLATE_DETAILS_V3`. Every required variable must be supplied with exact names and types.\n\n---\n\n### 5. Check Video Processing Status\nPoll the processing status and retrieve metadata for a video being generated.\n\n**Tool:** `HEYGEN_RETRIEVE_VIDEO_STATUS_DETAILS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `video_id` | string | Yes | Video ID returned from the generation API |\n\nReturned URLs expire after 7 days but can be regenerated by calling this endpoint again.\n\n---\n\n### 6. Get Shareable Video URL\nGenerate a public, shareable link that allows anyone to view the video without authentication.\n\n**Tool:** `HEYGEN_RETRIEVE_SHARABLE_VIDEO_URL`\n\nProvide the `video_id` to receive a public URL for distribution.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **All template variables required** | `HEYGEN_V2_TEMPLATE_GENERATE` demands every variable from `HEYGEN_RETRIEVE_TEMPLATE_DETAILS_V3` with exact names and types -- missing or misnamed fields break scenes or fail generation |\n| **Always inspect templates first** | Never skip `HEYGEN_RETRIEVE_TEMPLATE_DETAILS_V3` before generation -- multi-scene templates have complex variable structures |\n| **Video URLs expire** | URLs from `HEYGEN_RETRIEVE_VIDEO_STATUS_DETAILS` expire after 7 days; regenerate by calling the endpoint again |\n| **Paginated avatar lists** | `HEYGEN_V2_AVATARS` may return paginated results -- additional calls may be needed for the full library |\n| **Processing time varies** | Video generation is asynchronous; poll `HEYGEN_RETRIEVE_VIDEO_STATUS_DETAILS` until status is complete before using output URLs |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `HEYGEN_V2_TEMPLATES` | List available video templates |\n| `HEYGEN_RETRIEVE_TEMPLATE_DETAILS_V3` | Get template variables and scene structure |\n| `HEYGEN_V2_AVATARS` | Browse available AI avatars |\n| `HEYGEN_V2_TEMPLATE_GENERATE` | Generate video from a template |\n| `HEYGEN_RETRIEVE_VIDEO_STATUS_DETAILS` | Check video processing status and get URLs |\n| `HEYGEN_RETRIEVE_SHARABLE_VIDEO_URL` | Get a public shareable video link |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/heyreach-automation/SKILL.md",
    "content": "---\nname: heyreach-automation\ndescription: \"Automate Heyreach tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Heyreach Automation via Rube MCP\n\nAutomate Heyreach operations through Composio's Heyreach toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/heyreach](https://composio.dev/toolkits/heyreach)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Heyreach connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `heyreach`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `heyreach`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Heyreach operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Heyreach task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"heyreach\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Heyreach-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `heyreach` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/heyzine-automation/SKILL.md",
    "content": "---\nname: heyzine-automation\ndescription: \"Automate Heyzine tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Heyzine Automation via Rube MCP\n\nAutomate Heyzine operations through Composio's Heyzine toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/heyzine](https://composio.dev/toolkits/heyzine)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Heyzine connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `heyzine`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `heyzine`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Heyzine operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Heyzine task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"heyzine\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Heyzine-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `heyzine` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/highergov-automation/SKILL.md",
    "content": "---\nname: highergov-automation\ndescription: \"Automate Highergov tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Highergov Automation via Rube MCP\n\nAutomate Highergov operations through Composio's Highergov toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/highergov](https://composio.dev/toolkits/highergov)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Highergov connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `highergov`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `highergov`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Highergov operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Highergov task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"highergov\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Highergov-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `highergov` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/highlevel-automation/SKILL.md",
    "content": "---\nname: highlevel-automation\ndescription: \"Automate Highlevel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Highlevel Automation via Rube MCP\n\nAutomate Highlevel operations through Composio's Highlevel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/highlevel](https://composio.dev/toolkits/highlevel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Highlevel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `highlevel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `highlevel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Highlevel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Highlevel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"highlevel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Highlevel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `highlevel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/honeybadger-automation/SKILL.md",
    "content": "---\nname: honeybadger-automation\ndescription: \"Automate Honeybadger tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Honeybadger Automation via Rube MCP\n\nAutomate Honeybadger operations through Composio's Honeybadger toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/honeybadger](https://composio.dev/toolkits/honeybadger)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Honeybadger connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `honeybadger`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `honeybadger`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Honeybadger operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Honeybadger task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"honeybadger\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Honeybadger-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `honeybadger` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/honeyhive-automation/SKILL.md",
    "content": "---\nname: honeyhive-automation\ndescription: \"Automate Honeyhive tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Honeyhive Automation via Rube MCP\n\nAutomate Honeyhive operations through Composio's Honeyhive toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/honeyhive](https://composio.dev/toolkits/honeyhive)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Honeyhive connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `honeyhive`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `honeyhive`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Honeyhive operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Honeyhive task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"honeyhive\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Honeyhive-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `honeyhive` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hookdeck-automation/SKILL.md",
    "content": "---\nname: hookdeck-automation\ndescription: \"Automate Hookdeck tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hookdeck Automation via Rube MCP\n\nAutomate Hookdeck operations through Composio's Hookdeck toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hookdeck](https://composio.dev/toolkits/hookdeck)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hookdeck connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hookdeck`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hookdeck`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hookdeck operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hookdeck task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hookdeck\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hookdeck-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hookdeck` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hotspotsystem-automation/SKILL.md",
    "content": "---\nname: hotspotsystem-automation\ndescription: \"Automate Hotspotsystem tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hotspotsystem Automation via Rube MCP\n\nAutomate Hotspotsystem operations through Composio's Hotspotsystem toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hotspotsystem](https://composio.dev/toolkits/hotspotsystem)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hotspotsystem connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hotspotsystem`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hotspotsystem`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hotspotsystem operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hotspotsystem task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hotspotsystem\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hotspotsystem-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hotspotsystem` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/html-to-image-automation/SKILL.md",
    "content": "---\nname: html-to-image-automation\ndescription: \"Automate Html To Image tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Html To Image Automation via Rube MCP\n\nAutomate Html To Image operations through Composio's Html To Image toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/html_to_image](https://composio.dev/toolkits/html_to_image)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Html To Image connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `html_to_image`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `html_to_image`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Html To Image operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Html To Image task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"html_to_image\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Html To Image-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `html_to_image` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/humanitix-automation/SKILL.md",
    "content": "---\nname: humanitix-automation\ndescription: \"Automate Humanitix tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Humanitix Automation via Rube MCP\n\nAutomate Humanitix operations through Composio's Humanitix toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/humanitix](https://composio.dev/toolkits/humanitix)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Humanitix connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `humanitix`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `humanitix`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Humanitix operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Humanitix task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"humanitix\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Humanitix-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `humanitix` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/humanloop-automation/SKILL.md",
    "content": "---\nname: humanloop-automation\ndescription: \"Automate Humanloop tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Humanloop Automation via Rube MCP\n\nAutomate Humanloop operations through Composio's Humanloop toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/humanloop](https://composio.dev/toolkits/humanloop)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Humanloop connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `humanloop`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `humanloop`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Humanloop operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Humanloop task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"humanloop\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Humanloop-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `humanloop` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hunter-automation/SKILL.md",
    "content": "---\nname: Hunter Automation\ndescription: \"Automate Hunter.io email intelligence -- search domains for email addresses, find specific contacts, verify email deliverability, manage leads, and monitor account usage -- using natural language through the Composio MCP integration.\"\ncategory: email-intelligence\nrequires:\n  mcp:\n    - rube\n---\n\n# Hunter Automation\n\nPower your outreach with Hunter.io -- discover email addresses by domain, find specific people's emails, verify deliverability, save leads, and track your API usage -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/hunter](https://composio.dev/toolkits/hunter)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Hunter.io account when prompted (API key authentication).\n3. Start issuing natural language commands to find and verify emails.\n\n---\n\n## Core Workflows\n\n### 1. Search Domain for Email Addresses\nDiscover all publicly available email addresses for a given domain or company, with filtering by department, seniority, and type.\n\n**Tool:** `HUNTER_DOMAIN_SEARCH`\n\n**Example prompt:**\n> \"Find all executive email addresses at stripe.com using Hunter\"\n\n**Key parameters:**\n- `domain` -- Domain to search (e.g., \"stripe.com\"). Required if `company` not provided.\n- `company` -- Company name to search (e.g., \"Stripe\"). Required if `domain` not provided.\n- `type` -- Filter by \"personal\" or \"generic\" emails\n- `seniority` -- Filter by levels: \"junior\", \"senior\", \"executive\" (array)\n- `department` -- Filter by departments: \"executive\", \"it\", \"finance\", \"sales\", etc. (array)\n- `required_field` -- Require specific fields: \"full_name\", \"position\", \"phone_number\" (array)\n- `limit` -- Max results per request (1-100, default 10; free/basic plans limited to 10)\n- `offset` -- Skip results for pagination (default 0)\n\n---\n\n### 2. Find a Specific Person's Email\nInfer the most likely email address for a person given their name and domain or company.\n\n**Tool:** `HUNTER_EMAIL_FINDER`\n\n**Example prompt:**\n> \"Find the email for Alexis Ohanian at reddit.com using Hunter\"\n\n**Key parameters:**\n- `domain` -- Target domain (e.g., \"reddit.com\"). Takes precedence over `company`.\n- `company` -- Company name (e.g., \"Reddit\"). Used if domain not provided.\n- Name (one of these combinations required):\n  - `first_name` + `last_name` (e.g., \"Alexis\" + \"Ohanian\")\n  - `full_name` (e.g., \"Alexis Ohanian\")\n- `max_duration` -- Max request duration in seconds (3-20, default 10). Longer durations yield more accurate results.\n\n---\n\n### 3. Verify Email Deliverability\nCheck whether an email address is valid, deliverable, and safe to send to.\n\n**Tool:** `HUNTER_EMAIL_VERIFIER`\n\n**Example prompt:**\n> \"Verify if john.doe@example.com is a valid email address\"\n\n**Key parameters:**\n- `email` (required) -- The email address to verify (e.g., \"john.doe@example.com\")\n\n**Response includes:** verification status, deliverability score, MX record validation, and risk assessment.\n\n---\n\n### 4. Get Email Volume Estimates\nCheck how many email addresses Hunter has for a domain or company -- this call is free and does not consume API credits.\n\n**Tool:** `HUNTER_EMAIL_COUNT`\n\n**Example prompt:**\n> \"How many email addresses does Hunter have for stripe.com?\"\n\n**Key parameters:**\n- `domain` -- Domain to query (e.g., \"stripe.com\"). Required if `company` not provided.\n- `company` -- Company name (min 3 characters). Required if `domain` not provided.\n- `type` -- Filter count by \"personal\" or \"generic\" emails\n\n**Returns:** Total count with breakdowns by type, department, and seniority level.\n\n---\n\n### 5. Save and Manage Leads\nCreate or update leads by email in a single upsert call -- no need to check existence first.\n\n**Tool:** `HUNTER_UPSERT_LEAD`\n\n**Example prompt:**\n> \"Save john@stripe.com as a lead in Hunter with name John Doe, position CTO\"\n\n**Key parameters:**\n- `email` -- Lead's email address (primary identifier for upsert)\n- Name, position, company, and other lead metadata\n\n---\n\n### 6. Check Account Usage and Limits\nReview your Hunter account plan details, remaining searches, and verification quotas before running bulk operations.\n\n**Tool:** `HUNTER_ACCOUNT_INFORMATION`\n\n**Example prompt:**\n> \"How many Hunter API searches do I have left this month?\"\n\n**Key parameters:** None required.\n\n---\n\n## Known Pitfalls\n\n- **HTTP 401 means invalid credentials**: `authentication_failed` errors indicate an invalid or expired API key. Fix before attempting bulk operations.\n- **Email counts are estimates**: `HUNTER_EMAIL_COUNT` returns approximate numbers for sizing and prioritization, not guaranteed retrievable email counts.\n- **Domain search uses offset pagination**: `HUNTER_DOMAIN_SEARCH` paginates via `limit`/`offset`. Do not assume the first page is complete -- continue fetching until results are empty or you hit a cap.\n- **Empty results are not errors**: `HUNTER_DOMAIN_SEARCH` can return `emails: []` with no error. Treat as \"no data found\" and continue, rather than retrying as a failure.\n- **Verification status nuances**: `accept_all` or `risky` statuses from `HUNTER_EMAIL_VERIFIER` indicate uncertainty. Exclude these from strict deliverability workflows or handle them separately.\n- **Free/basic plan limits**: Free and basic plans limit `HUNTER_DOMAIN_SEARCH` to 10 results per request. Higher limits require a paid plan.\n- **Domain format matters**: Use bare domains like \"stripe.com\" -- do not include protocol (\"https://\") or \"www.\" prefix.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| Search domain emails | `HUNTER_DOMAIN_SEARCH` | `domain` or `company` |\n| Find person's email | `HUNTER_EMAIL_FINDER` | Name + (`domain` or `company`) |\n| Verify email | `HUNTER_EMAIL_VERIFIER` | `email` |\n| Get email count | `HUNTER_EMAIL_COUNT` | `domain` or `company` |\n| Save/update lead | `HUNTER_UPSERT_LEAD` | `email` |\n| Check account | `HUNTER_ACCOUNT_INFORMATION` | None |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hypeauditor-automation/SKILL.md",
    "content": "---\nname: hypeauditor-automation\ndescription: \"Automate Hypeauditor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hypeauditor Automation via Rube MCP\n\nAutomate Hypeauditor operations through Composio's Hypeauditor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hypeauditor](https://composio.dev/toolkits/hypeauditor)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hypeauditor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hypeauditor`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hypeauditor`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hypeauditor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hypeauditor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hypeauditor\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hypeauditor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hypeauditor` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hyperbrowser-automation/SKILL.md",
    "content": "---\nname: hyperbrowser-automation\ndescription: \"Automate Hyperbrowser tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hyperbrowser Automation via Rube MCP\n\nAutomate Hyperbrowser operations through Composio's Hyperbrowser toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hyperbrowser](https://composio.dev/toolkits/hyperbrowser)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hyperbrowser connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperbrowser`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperbrowser`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hyperbrowser operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hyperbrowser task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hyperbrowser\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hyperbrowser-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperbrowser` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hyperise-automation/SKILL.md",
    "content": "---\nname: hyperise-automation\ndescription: \"Automate Hyperise tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hyperise Automation via Rube MCP\n\nAutomate Hyperise operations through Composio's Hyperise toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hyperise](https://composio.dev/toolkits/hyperise)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hyperise connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperise`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperise`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hyperise operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hyperise task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hyperise\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hyperise-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hyperise` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/hystruct-automation/SKILL.md",
    "content": "---\nname: hystruct-automation\ndescription: \"Automate Hystruct tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Hystruct Automation via Rube MCP\n\nAutomate Hystruct operations through Composio's Hystruct toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/hystruct](https://composio.dev/toolkits/hystruct)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Hystruct connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `hystruct`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `hystruct`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Hystruct operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Hystruct task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"hystruct\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Hystruct-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `hystruct` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/icims-talent-cloud-automation/SKILL.md",
    "content": "---\nname: icims-talent-cloud-automation\ndescription: \"Automate Icims Talent Cloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Icims Talent Cloud Automation via Rube MCP\n\nAutomate Icims Talent Cloud operations through Composio's Icims Talent Cloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/icims_talent_cloud](https://composio.dev/toolkits/icims_talent_cloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Icims Talent Cloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `icims_talent_cloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `icims_talent_cloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Icims Talent Cloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Icims Talent Cloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"icims_talent_cloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Icims Talent Cloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `icims_talent_cloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/icypeas-automation/SKILL.md",
    "content": "---\nname: icypeas-automation\ndescription: \"Automate Icypeas tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Icypeas Automation via Rube MCP\n\nAutomate Icypeas operations through Composio's Icypeas toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/icypeas](https://composio.dev/toolkits/icypeas)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Icypeas connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `icypeas`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `icypeas`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Icypeas operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Icypeas task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"icypeas\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Icypeas-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `icypeas` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/idea-scale-automation/SKILL.md",
    "content": "---\nname: idea-scale-automation\ndescription: \"Automate Idea Scale tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Idea Scale Automation via Rube MCP\n\nAutomate Idea Scale operations through Composio's Idea Scale toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/idea_scale](https://composio.dev/toolkits/idea_scale)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Idea Scale connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `idea_scale`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `idea_scale`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Idea Scale operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Idea Scale task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"idea_scale\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Idea Scale-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `idea_scale` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/identitycheck-automation/SKILL.md",
    "content": "---\nname: identitycheck-automation\ndescription: \"Automate Identitycheck tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Identitycheck Automation via Rube MCP\n\nAutomate Identitycheck operations through Composio's Identitycheck toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/identitycheck](https://composio.dev/toolkits/identitycheck)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Identitycheck connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `identitycheck`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `identitycheck`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Identitycheck operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Identitycheck task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"identitycheck\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Identitycheck-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `identitycheck` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ignisign-automation/SKILL.md",
    "content": "---\nname: ignisign-automation\ndescription: \"Automate Ignisign tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ignisign Automation via Rube MCP\n\nAutomate Ignisign operations through Composio's Ignisign toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ignisign](https://composio.dev/toolkits/ignisign)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ignisign connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ignisign`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ignisign`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ignisign operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ignisign task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ignisign\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ignisign-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ignisign` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/imagekit-io-automation/SKILL.md",
    "content": "---\nname: imagekit-io-automation\ndescription: \"Automate Imagekit IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Imagekit IO Automation via Rube MCP\n\nAutomate Imagekit IO operations through Composio's Imagekit IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/imagekit_io](https://composio.dev/toolkits/imagekit_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Imagekit IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `imagekit_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `imagekit_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Imagekit IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Imagekit IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"imagekit_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Imagekit IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `imagekit_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/imgbb-automation/SKILL.md",
    "content": "---\nname: imgbb-automation\ndescription: \"Automate Imgbb tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Imgbb Automation via Rube MCP\n\nAutomate Imgbb operations through Composio's Imgbb toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/imgbb](https://composio.dev/toolkits/imgbb)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Imgbb connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `imgbb`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `imgbb`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Imgbb operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Imgbb task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"imgbb\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Imgbb-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `imgbb` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/imgix-automation/SKILL.md",
    "content": "---\nname: imgix-automation\ndescription: \"Automate Imgix tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Imgix Automation via Rube MCP\n\nAutomate Imgix operations through Composio's Imgix toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/imgix](https://composio.dev/toolkits/imgix)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Imgix connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `imgix`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `imgix`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Imgix operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Imgix task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"imgix\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Imgix-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `imgix` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/influxdb-cloud-automation/SKILL.md",
    "content": "---\nname: influxdb-cloud-automation\ndescription: \"Automate Influxdb Cloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Influxdb Cloud Automation via Rube MCP\n\nAutomate Influxdb Cloud operations through Composio's Influxdb Cloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/influxdb_cloud](https://composio.dev/toolkits/influxdb_cloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Influxdb Cloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `influxdb_cloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `influxdb_cloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Influxdb Cloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Influxdb Cloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"influxdb_cloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Influxdb Cloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `influxdb_cloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/insighto-ai-automation/SKILL.md",
    "content": "---\nname: insighto-ai-automation\ndescription: \"Automate Insighto AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Insighto AI Automation via Rube MCP\n\nAutomate Insighto AI operations through Composio's Insighto AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/insighto_ai](https://composio.dev/toolkits/insighto_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Insighto AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `insighto_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `insighto_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Insighto AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Insighto AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"insighto_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Insighto AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `insighto_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/instacart-automation/SKILL.md",
    "content": "---\nname: instacart-automation\ndescription: \"Automate Instacart tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Instacart Automation via Rube MCP\n\nAutomate Instacart operations through Composio's Instacart toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/instacart](https://composio.dev/toolkits/instacart)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Instacart connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `instacart`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `instacart`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Instacart operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Instacart task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"instacart\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Instacart-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `instacart` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/instantly-automation/SKILL.md",
    "content": "---\nname: Instantly Automation\ndescription: \"Automate Instantly cold email outreach -- manage campaigns, sending accounts, lead lists, bulk lead imports, and campaign analytics -- using natural language through the Composio MCP integration.\"\ncategory: email-outreach\nrequires:\n  mcp:\n    - rube\n---\n\n# Instantly Automation\n\nAutomate your cold email outreach with Instantly -- create and manage campaigns with multi-step sequences, configure sending schedules, import leads in bulk, manage sending accounts, and track campaign performance -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/instantly](https://composio.dev/toolkits/instantly)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Instantly account when prompted (API key authentication).\n3. Start issuing natural language commands to manage your outreach campaigns.\n\n---\n\n## Core Workflows\n\n### 1. List Sending Accounts\nRetrieve all email accounts configured in your Instantly workspace, with filtering by status and provider.\n\n**Tool:** `INSTANTLY_LIST_ACCOUNTS`\n\n**Example prompt:**\n> \"Show all active sending accounts in my Instantly workspace\"\n\n**Key parameters:**\n- `status` -- Filter by status: `1` (Active), `2` (Paused), `-1` (Connection Error), `-2` (Soft Bounce Error), `-3` (Sending Error)\n- `provider_code` -- Filter by provider: `1` (Custom IMAP/SMTP), `2` (Google), `3` (Microsoft), `4` (AWS)\n- `search` -- Search by email substring or domain\n- `limit` -- Max items (1-100)\n- `starting_after` -- Pagination cursor from previous response\n- `tag_ids` -- Comma-separated tag UUIDs\n\n---\n\n### 2. Create a Campaign\nLaunch a new outreach campaign with scheduling, email sequences, A/B testing variants, and sending configuration.\n\n**Tool:** `INSTANTLY_CREATE_CAMPAIGN`\n\n**Example prompt:**\n> \"Create an Instantly campaign called 'Q1 Outreach' that sends Monday-Friday 9am-5pm Central time with a 3-step email sequence\"\n\n**Key parameters:**\n- `name` (required) -- Campaign name\n- `campaign_schedule` (required) -- Schedule configuration:\n  - `schedules` (required) -- Array of schedule objects, each with:\n    - `name` -- Schedule name\n    - `timing` -- `{from: \"09:00\", to: \"17:00\"}` (HH:mm format)\n    - `days` -- Map of day index strings \"0\" (Sun) to \"6\" (Sat) to booleans\n    - `timezone` -- Supported values include \"America/Chicago\", \"America/Detroit\", \"America/Boise\", \"America/Anchorage\"\n  - `start_date` / `end_date` -- ISO 8601 dates\n- `email_list` -- Array of sending account email addresses (must be pre-configured accounts; use `INSTANTLY_LIST_ACCOUNTS` to discover valid addresses)\n- `sequences` -- Array (only first element used) containing:\n  - `steps` -- Array of step objects with:\n    - `type` -- Must be \"email\"\n    - `delay` -- Days before NEXT email (integer, min 0)\n    - `variants` -- Array of `{subject, body}` objects for A/B testing\n- `daily_limit` -- Daily sending cap\n- `email_gap` -- Minutes between emails\n- `stop_on_reply` -- Stop campaign when lead replies (boolean)\n- `stop_on_auto_reply` -- Stop on auto-replies (boolean)\n- `open_tracking` / `link_tracking` -- Enable tracking (booleans)\n\n**Timezone notes:**\n- Verified working: \"America/Chicago\" (Central), \"America/Detroit\" (Eastern), \"America/Boise\" (Mountain)\n- Auto-mapped: \"America/New_York\" maps to \"America/Detroit\", \"America/Denver\" maps to \"America/Boise\"\n- NOT supported: \"America/Los_Angeles\", \"US/Pacific\" -- use \"America/Anchorage\" or \"America/Dawson\" as alternatives\n\n---\n\n### 3. Update Campaign Settings\nModify an existing campaign's schedule, sending limits, sequences, or tracking settings.\n\n**Tool:** `INSTANTLY_UPDATE_CAMPAIGN`\n\n**Example prompt:**\n> \"Update my Instantly campaign to increase the daily limit to 100 and enable open tracking\"\n\n**Key parameters:**\n- `id` (required) -- Campaign UUID\n- Any combination of: `name`, `campaign_schedule`, `email_list`, `sequences`, `daily_limit`, `email_gap`, `stop_on_reply`, `open_tracking`, `link_tracking`, etc.\n- Set any parameter to `null` to unset it\n\n---\n\n### 4. Manage Lead Lists and Bulk Import\nCreate dedicated lead lists and import prospects in bulk for campaign targeting.\n\n**Tools:** `INSTANTLY_CREATE_LEAD_LIST`, `INSTANTLY_ADD_LEADS_BULK`\n\n**Example prompt:**\n> \"Create a lead list called 'Q1 Prospects' and add 50 leads to my Instantly campaign\"\n\n**Key parameters for creating lead lists:**\n- List name and configuration\n\n**Key parameters for bulk lead import:**\n- Campaign or list ID to import into\n- Array of lead objects with email and metadata\n- Duplicate handling options\n- Lead verification settings\n\n---\n\n### 5. Review Campaign Details\nRetrieve full campaign configuration to verify settings, inspect sequences, or prepare for updates.\n\n**Tool:** `INSTANTLY_GET_CAMPAIGN`\n\n**Example prompt:**\n> \"Show me the full details of my Instantly campaign\"\n\n**Key parameters:**\n- `id` (required) -- Campaign UUID\n\n---\n\n### 6. List All Campaigns\nEnumerate all campaigns in your workspace with optional filters and pagination.\n\n**Tool:** `INSTANTLY_LIST_CAMPAIGNS`\n\n**Example prompt:**\n> \"List all my Instantly campaigns\"\n\n**Key parameters:**\n- Optional filters and pagination parameters\n\n---\n\n## Known Pitfalls\n\n- **Timezone support is limited**: The Instantly API accepts a restricted set of timezone strings. Pacific Time (\"America/Los_Angeles\") is NOT supported. Use \"America/Anchorage\" (UTC-9/UTC-8) or \"America/Dawson\" (UTC-7 year-round) as alternatives.\n- **Invalid schedule payloads cause 400 errors**: A malformed `campaign_schedule` (missing `days`, `from`, `to`, or `schedules`) triggers HTTP 400. Repeated 400s indicate payload issues, not transient failures.\n- **Sequences must be complete**: Each sequence step requires a valid `type` (\"email\"), `delay`, and at least one variant with both `subject` and `body`. Incomplete variants block campaign creation.\n- **Only first sequence element is used**: The API only processes `sequences[0]`. Additional sequences are ignored.\n- **email_list must reference existing accounts**: The `email_list` field requires email addresses of pre-configured sending accounts in your Instantly workspace, not arbitrary recipient addresses. Always use `INSTANTLY_LIST_ACCOUNTS` to discover valid sending addresses.\n- **401 scope errors on campaign creation**: Campaign creation can fail with \"Invalid scope. Required: campaigns:create\". Update your API key permissions before retrying writes.\n- **Read-back fields may differ**: Field names in `INSTANTLY_GET_CAMPAIGN` responses may differ from create payloads (e.g., `timing.from_` vs `timing.from`). Parse defensively.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| List sending accounts | `INSTANTLY_LIST_ACCOUNTS` | None (optional filters) |\n| Create campaign | `INSTANTLY_CREATE_CAMPAIGN` | `name`, `campaign_schedule` |\n| Update campaign | `INSTANTLY_UPDATE_CAMPAIGN` | `id` |\n| Get campaign details | `INSTANTLY_GET_CAMPAIGN` | `id` |\n| List campaigns | `INSTANTLY_LIST_CAMPAIGNS` | None (optional filters) |\n| Create lead list | `INSTANTLY_CREATE_LEAD_LIST` | List name |\n| Bulk import leads | `INSTANTLY_ADD_LEADS_BULK` | Campaign/list ID, leads |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/intelliprint-automation/SKILL.md",
    "content": "---\nname: intelliprint-automation\ndescription: \"Automate Intelliprint tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Intelliprint Automation via Rube MCP\n\nAutomate Intelliprint operations through Composio's Intelliprint toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/intelliprint](https://composio.dev/toolkits/intelliprint)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Intelliprint connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `intelliprint`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `intelliprint`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Intelliprint operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Intelliprint task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"intelliprint\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Intelliprint-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `intelliprint` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/interzoid-automation/SKILL.md",
    "content": "---\nname: interzoid-automation\ndescription: \"Automate Interzoid tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Interzoid Automation via Rube MCP\n\nAutomate Interzoid operations through Composio's Interzoid toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/interzoid](https://composio.dev/toolkits/interzoid)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Interzoid connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `interzoid`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `interzoid`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Interzoid operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Interzoid task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"interzoid\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Interzoid-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `interzoid` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ip2location-automation/SKILL.md",
    "content": "---\nname: ip2location-automation\ndescription: \"Automate Ip2location tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ip2location Automation via Rube MCP\n\nAutomate Ip2location operations through Composio's Ip2location toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ip2location](https://composio.dev/toolkits/ip2location)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ip2location connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ip2location operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ip2location task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ip2location\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ip2location-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ip2location-io-automation/SKILL.md",
    "content": "---\nname: ip2location-io-automation\ndescription: \"Automate Ip2location IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ip2location IO Automation via Rube MCP\n\nAutomate Ip2location IO operations through Composio's Ip2location IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ip2location_io](https://composio.dev/toolkits/ip2location_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ip2location IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ip2location IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ip2location IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ip2location_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ip2location IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2location_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ip2proxy-automation/SKILL.md",
    "content": "---\nname: ip2proxy-automation\ndescription: \"Automate Ip2proxy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ip2proxy Automation via Rube MCP\n\nAutomate Ip2proxy operations through Composio's Ip2proxy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ip2proxy](https://composio.dev/toolkits/ip2proxy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ip2proxy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2proxy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2proxy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ip2proxy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ip2proxy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ip2proxy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ip2proxy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2proxy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ip2whois-automation/SKILL.md",
    "content": "---\nname: ip2whois-automation\ndescription: \"Automate Ip2whois tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ip2whois Automation via Rube MCP\n\nAutomate Ip2whois operations through Composio's Ip2whois toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ip2whois](https://composio.dev/toolkits/ip2whois)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ip2whois connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2whois`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2whois`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ip2whois operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ip2whois task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ip2whois\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ip2whois-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ip2whois` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ipdata-co-automation/SKILL.md",
    "content": "---\nname: ipdata-co-automation\ndescription: \"Automate Ipdata co tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ipdata co Automation via Rube MCP\n\nAutomate Ipdata co operations through Composio's Ipdata co toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ipdata_co](https://composio.dev/toolkits/ipdata_co)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ipdata co connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ipdata_co`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ipdata_co`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ipdata co operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ipdata co task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ipdata_co\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ipdata co-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ipdata_co` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ipinfo-io-automation/SKILL.md",
    "content": "---\nname: ipinfo-io-automation\ndescription: \"Automate Ipinfo IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ipinfo IO Automation via Rube MCP\n\nAutomate Ipinfo IO operations through Composio's Ipinfo IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ipinfo_io](https://composio.dev/toolkits/ipinfo_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ipinfo IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ipinfo_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ipinfo_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ipinfo IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ipinfo IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ipinfo_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ipinfo IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ipinfo_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/iqair-airvisual-automation/SKILL.md",
    "content": "---\nname: iqair-airvisual-automation\ndescription: \"Automate Iqair Airvisual tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Iqair Airvisual Automation via Rube MCP\n\nAutomate Iqair Airvisual operations through Composio's Iqair Airvisual toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/iqair_airvisual](https://composio.dev/toolkits/iqair_airvisual)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Iqair Airvisual connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `iqair_airvisual`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `iqair_airvisual`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Iqair Airvisual operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Iqair Airvisual task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"iqair_airvisual\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Iqair Airvisual-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `iqair_airvisual` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/jigsawstack-automation/SKILL.md",
    "content": "---\nname: jigsawstack-automation\ndescription: \"Automate Jigsawstack tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Jigsawstack Automation via Rube MCP\n\nAutomate Jigsawstack operations through Composio's Jigsawstack toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/jigsawstack](https://composio.dev/toolkits/jigsawstack)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Jigsawstack connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `jigsawstack`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `jigsawstack`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Jigsawstack operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Jigsawstack task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"jigsawstack\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Jigsawstack-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `jigsawstack` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/jobnimbus-automation/SKILL.md",
    "content": "---\nname: jobnimbus-automation\ndescription: \"Automate Jobnimbus tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Jobnimbus Automation via Rube MCP\n\nAutomate Jobnimbus operations through Composio's Jobnimbus toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/jobnimbus](https://composio.dev/toolkits/jobnimbus)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Jobnimbus connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `jobnimbus`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `jobnimbus`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Jobnimbus operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Jobnimbus task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"jobnimbus\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Jobnimbus-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `jobnimbus` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/jotform-automation/SKILL.md",
    "content": "---\nname: Jotform Automation\ndescription: \"Automate Jotform form listing, user management, activity history, folder organization, and plan inspection through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Jotform Automation\n\nAutomate Jotform workflows -- list and search forms, inspect user details, browse activity history, manage folders and labels, and check plan limits -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/jotform](https://composio.dev/toolkits/jotform)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Jotform account when prompted (API key auth via Composio)\n3. Start issuing natural language commands for Jotform automation\n\n---\n\n## Core Workflows\n\n### 1. List and Search Forms\n\nRetrieve all forms created by the authenticated user with search, filtering, sorting, and pagination.\n\n**Tool:** `JOTFORM_GET_USER_FORMS`\n\nKey parameters:\n- `search` -- search query to filter forms by name or content\n- `limit` -- number of forms to return\n- `offset` -- offset for pagination\n- `orderby` -- field to order by\n- `sorting` -- sorting direction: `ASC` or `DESC`\n- `folder` -- filter by folder ID\n\nExample prompt:\n> \"List all my Jotform forms that contain 'feedback' in the name, sorted by most recent\"\n\n---\n\n### 2. Get User Account Details\n\nRetrieve details about the authenticated user including account type, usage statistics, and limits.\n\n**Tool:** `JOTFORM_GET_USER_DETAILS`\n\nNo parameters required. Returns account info such as username, email, account type, form count, submission count, and usage limits.\n\nExample prompt:\n> \"Show me my Jotform account details and current usage\"\n\n---\n\n### 3. Browse Activity History\n\nFetch user activity records for auditing, filtered by action type and date range.\n\n**Tool:** `JOTFORM_GET_USER_HISTORY`\n\nKey parameters:\n- `action` -- filter by action type (e.g., `formCreation`, `userLogin`, `formUpdate`, `apiKeyCreated`, `userLogout`)\n- `date` -- predefined date range: `lastWeek`, `lastMonth`, `last3Months`, `last6Months`, `lastYear`, `all`\n- `startDate` -- custom start date in `MM/DD/YYYY` format\n- `endDate` -- custom end date in `MM/DD/YYYY` format\n- `sortBy` -- sort order: `ASC` or `DESC`\n\nExample prompt:\n> \"Show me all form creation activity from the last month, sorted newest first\"\n\n---\n\n### 4. Manage Folders and Labels\n\nBrowse the folder/label structure for organizing forms.\n\n**Tool:** `JOTFORM_GET_USER_FOLDERS`\n\nKey parameters:\n- `add_resources` -- set to `true` to include label resources (forms) in the response\n- `owner` -- owner username or workspace/team ID (conditionally required for some accounts)\n\n> Jotform has migrated from folders to labels. This tool uses the `GET /user/labels` endpoint.\n\nExample prompt:\n> \"List all my Jotform folders with their forms included\"\n\n---\n\n### 5. Check Plan Limits and Pricing\n\nRetrieve details about a specific Jotform system plan to understand limits and capabilities.\n\n**Tool:** `JOTFORM_GET_SYSTEM_PLAN`\n\nKey parameters:\n- `planName` -- the plan to inspect (required): `FREE`, `BRONZE`, `SILVER`, `GOLD`, or `PLATINUM`\n\nExample prompt:\n> \"What are the limits on the Jotform GOLD plan?\"\n\n---\n\n### 6. Full Form Management Workflow\n\nCombine tools for comprehensive form management:\n\n1. **Discover**: `JOTFORM_GET_USER_DETAILS` -- check account type and usage limits\n2. **Browse**: `JOTFORM_GET_USER_FORMS` -- list and search forms with filters\n3. **Organize**: `JOTFORM_GET_USER_FOLDERS` -- view folder structure with `add_resources=true`\n4. **Audit**: `JOTFORM_GET_USER_HISTORY` -- track form creation and modification activity\n5. **Plan**: `JOTFORM_GET_SYSTEM_PLAN` -- compare plan features before upgrading\n\nExample prompt:\n> \"Show me my account usage, list my recent forms, and tell me if I'm close to my plan limits\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| API key authentication | Jotform uses API key auth, not OAuth -- ensure valid API key is configured in the connection |\n| Folders migrated to labels | The folders endpoint now maps to Jotform's labels system; the API behavior may differ from legacy folder documentation |\n| Date format for history | Custom date filters use `MM/DD/YYYY` format (e.g., `01/15/2026`), not ISO 8601 |\n| Plan name must be exact | `planName` values are case-sensitive enum: `FREE`, `BRONZE`, `SILVER`, `GOLD`, `PLATINUM` |\n| Pagination is offset-based | Forms use `limit`/`offset` pagination, not cursor or page-based |\n| Owner field conditionally required | `JOTFORM_GET_USER_FOLDERS` may require the `owner` parameter for workspace/team accounts |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| List forms | `JOTFORM_GET_USER_FORMS` | `search`, `limit`, `offset`, `orderby` |\n| Get user details | `JOTFORM_GET_USER_DETAILS` | (none) |\n| Activity history | `JOTFORM_GET_USER_HISTORY` | `action`, `date`, `startDate`, `endDate` |\n| List folders/labels | `JOTFORM_GET_USER_FOLDERS` | `add_resources`, `owner` |\n| Check plan | `JOTFORM_GET_SYSTEM_PLAN` | `planName` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/jumpcloud-automation/SKILL.md",
    "content": "---\nname: jumpcloud-automation\ndescription: \"Automate Jumpcloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Jumpcloud Automation via Rube MCP\n\nAutomate Jumpcloud operations through Composio's Jumpcloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/jumpcloud](https://composio.dev/toolkits/jumpcloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Jumpcloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `jumpcloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `jumpcloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Jumpcloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Jumpcloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"jumpcloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Jumpcloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `jumpcloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/junglescout-automation/SKILL.md",
    "content": "---\nname: junglescout-automation\ndescription: \"Automate Junglescout tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Junglescout Automation via Rube MCP\n\nAutomate Junglescout operations through Composio's Junglescout toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/junglescout](https://composio.dev/toolkits/junglescout)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Junglescout connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `junglescout`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `junglescout`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Junglescout operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Junglescout task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"junglescout\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Junglescout-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `junglescout` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kadoa-automation/SKILL.md",
    "content": "---\nname: kadoa-automation\ndescription: \"Automate Kadoa tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kadoa Automation via Rube MCP\n\nAutomate Kadoa operations through Composio's Kadoa toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kadoa](https://composio.dev/toolkits/kadoa)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kadoa connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kadoa`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kadoa`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kadoa operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kadoa task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kadoa\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kadoa-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kadoa` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kaggle-automation/SKILL.md",
    "content": "---\nname: kaggle-automation\ndescription: \"Automate Kaggle tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kaggle Automation via Rube MCP\n\nAutomate Kaggle operations through Composio's Kaggle toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kaggle](https://composio.dev/toolkits/kaggle)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kaggle connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kaggle`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kaggle`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kaggle operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kaggle task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kaggle\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kaggle-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kaggle` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kaleido-automation/SKILL.md",
    "content": "---\nname: kaleido-automation\ndescription: \"Automate Kaleido tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kaleido Automation via Rube MCP\n\nAutomate Kaleido operations through Composio's Kaleido toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kaleido](https://composio.dev/toolkits/kaleido)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kaleido connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kaleido`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kaleido`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kaleido operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kaleido task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kaleido\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kaleido-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kaleido` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/keap-automation/SKILL.md",
    "content": "---\nname: keap-automation\ndescription: \"Automate Keap tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Keap Automation via Rube MCP\n\nAutomate Keap operations through Composio's Keap toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/keap](https://composio.dev/toolkits/keap)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Keap connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `keap`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `keap`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Keap operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Keap task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"keap\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Keap-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `keap` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/keen-io-automation/SKILL.md",
    "content": "---\nname: keen-io-automation\ndescription: \"Automate Keen IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Keen IO Automation via Rube MCP\n\nAutomate Keen IO operations through Composio's Keen IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/keen_io](https://composio.dev/toolkits/keen_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Keen IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `keen_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `keen_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Keen IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Keen IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"keen_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Keen IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `keen_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kickbox-automation/SKILL.md",
    "content": "---\nname: kickbox-automation\ndescription: \"Automate Kickbox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kickbox Automation via Rube MCP\n\nAutomate Kickbox operations through Composio's Kickbox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kickbox](https://composio.dev/toolkits/kickbox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kickbox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kickbox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kickbox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kickbox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kickbox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kickbox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kickbox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kickbox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kit-automation/SKILL.md",
    "content": "---\nname: kit-automation\ndescription: \"Automate Kit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kit Automation via Rube MCP\n\nAutomate Kit operations through Composio's Kit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kit](https://composio.dev/toolkits/kit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/klipfolio-automation/SKILL.md",
    "content": "---\nname: klipfolio-automation\ndescription: \"Automate Klipfolio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Klipfolio Automation via Rube MCP\n\nAutomate Klipfolio operations through Composio's Klipfolio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/klipfolio](https://composio.dev/toolkits/klipfolio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Klipfolio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `klipfolio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `klipfolio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Klipfolio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Klipfolio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"klipfolio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Klipfolio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `klipfolio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ko-fi-automation/SKILL.md",
    "content": "---\nname: ko-fi-automation\ndescription: \"Automate Ko Fi tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ko Fi Automation via Rube MCP\n\nAutomate Ko Fi operations through Composio's Ko Fi toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ko_fi](https://composio.dev/toolkits/ko_fi)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ko Fi connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ko_fi`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ko_fi`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ko Fi operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ko Fi task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ko_fi\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ko Fi-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ko_fi` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kommo-automation/SKILL.md",
    "content": "---\nname: Kommo Automation\ndescription: \"Automate Kommo CRM operations -- manage leads, pipelines, pipeline stages, tasks, and custom fields -- using natural language through the Composio MCP integration.\"\ncategory: crm\nrequires:\n  mcp:\n    - rube\n---\n\n# Kommo Automation\n\nManage your Kommo CRM sales pipeline -- list and filter leads, navigate pipeline stages, create and update deals, assign tasks, and work with custom fields -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/kommo](https://composio.dev/toolkits/kommo)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Kommo account when prompted (OAuth authentication).\n3. Start issuing natural language commands to manage your CRM.\n\n---\n\n## Core Workflows\n\n### 1. Navigate Pipelines and Stages\nList all lead pipelines, then drill into specific pipeline stages to understand your sales funnel structure.\n\n**Tools:** `KOMMO_LIST_LEADS_PIPELINES`, `KOMMO_LIST_PIPELINE_STAGES`\n\n**Example prompt:**\n> \"Show all my Kommo pipelines and the stages in my main sales pipeline\"\n\n**Key parameters for List Pipelines:** None required.\n\n**Key parameters for List Stages:**\n- `pipeline_id` (required) -- The pipeline ID to list stages for\n- `with_description` -- Include stage descriptions in the response (boolean)\n\n---\n\n### 2. List and Filter Leads\nRetrieve leads with powerful filtering by pipeline, status, date ranges, responsible users, price, and more.\n\n**Tool:** `KOMMO_LIST_LEADS`\n\n**Example prompt:**\n> \"Show all leads in pipeline 12345 created this week, sorted by newest first\"\n\n**Key parameters:**\n- `query` -- Free-text search across all filled fields\n- `filter_pipeline_ids` -- Filter by pipeline IDs (array of integers)\n- `filter_status` -- Filter by status within a pipeline: `{\"pipeline_id\": 123, \"status_id\": 456}`\n- `filter_responsible_user_ids` -- Filter by assigned user IDs\n- `filter_names` -- Filter by lead names\n- `filter_price` -- Filter by deal value\n- `filter_created_at` -- Date range: `{\"from\": <unix_timestamp>, \"to\": <unix_timestamp>}`\n- `filter_updated_at` -- Date range for last update\n- `filter_closed_at` -- Date range for closure\n- `order_by_created_at` -- Sort: \"asc\" or \"desc\"\n- `order_by_updated_at` -- Sort by update date\n- `limit` -- Max 250 per page\n- `page` -- Page number for pagination\n- `with_params` -- Additional data: \"contacts\", \"loss_reason\", \"catalog_elements\", \"source_id\"\n\n---\n\n### 3. Create New Leads\nAdd new deals to your Kommo pipeline with custom fields, tags, and pipeline placement.\n\n**Tool:** `KOMMO_CREATE_LEAD`\n\n**Example prompt:**\n> \"Create a new lead called 'Acme Corp Deal' worth $50,000 in pipeline 12345\"\n\n**Key parameters:**\n- `name` (required) -- Name of the lead/deal\n- `price` -- Deal value (integer)\n- `pipeline_id` -- Pipeline to add the lead to\n- `status_id` -- Stage within the pipeline (defaults to first stage of main pipeline)\n- `responsible_user_id` -- Assigned user ID\n- `custom_fields_values` -- Array of custom field value objects\n- `tags_to_add` -- Array of tags (by name or ID)\n- `created_by` -- User ID of creator (0 for robot)\n- `loss_reason_id` -- Reason for loss (if applicable)\n\n---\n\n### 4. Update Existing Leads\nModify lead properties including name, price, pipeline stage, responsible user, tags, and custom fields.\n\n**Tool:** `KOMMO_UPDATE_LEAD`\n\n**Example prompt:**\n> \"Move lead 789 to stage 456 in pipeline 123 and update the price to $75,000\"\n\n**Key parameters:**\n- Lead ID (required)\n- Any combination of: `name`, `price`, `pipeline_id`, `status_id`, `responsible_user_id`, `tags_to_add`, `tags_to_delete`, `custom_fields_values`\n\n---\n\n### 5. Create Tasks\nAssign follow-up tasks linked to leads, contacts, or companies.\n\n**Tool:** `KOMMO_CREATE_TASK`\n\n**Example prompt:**\n> \"Create a follow-up call task for lead 789 due tomorrow assigned to user 42\"\n\n**Key parameters:**\n- Task text/description\n- Entity type and ID (lead, contact, company)\n- Responsible user ID\n- Due date (Unix timestamp)\n- Task type\n\n---\n\n### 6. Discover Custom Fields\nList all custom fields for leads, contacts, or companies to understand your CRM schema.\n\n**Tool:** `KOMMO_LIST_CUSTOM_FIELDS`\n\n**Example prompt:**\n> \"What custom fields are available for leads in Kommo?\"\n\n**Key parameters:**\n- Entity type (leads, contacts, companies)\n\n---\n\n## Known Pitfalls\n\n- **Date filters use Unix timestamps**: All date range filters (`filter_created_at`, `filter_updated_at`, `filter_closed_at`) require Unix timestamp format in `{\"from\": <timestamp>, \"to\": <timestamp>}` structure, not ISO8601 strings.\n- **Pipeline and stage IDs are required**: To filter leads by status, you need both `pipeline_id` and `status_id`. Always call `KOMMO_LIST_LEADS_PIPELINES` and `KOMMO_LIST_PIPELINE_STAGES` first to discover valid IDs.\n- **Max 250 leads per page**: The `limit` parameter caps at 250. For large datasets, implement pagination using the `page` parameter.\n- **Custom field values format**: Custom fields use a specific nested object format. Use `KOMMO_LIST_CUSTOM_FIELDS` to discover field IDs and expected value formats before setting values.\n- **Status filter requires both IDs**: The `filter_status` parameter requires both `pipeline_id` and `status_id` as a combined object -- you cannot filter by status alone.\n- **Created_by 0 means robot**: When setting `created_by` or `updated_by` to 0, the action is attributed to a robot/automation, not a human user.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| List pipelines | `KOMMO_LIST_LEADS_PIPELINES` | None |\n| List pipeline stages | `KOMMO_LIST_PIPELINE_STAGES` | `pipeline_id` |\n| List leads | `KOMMO_LIST_LEADS` | None (optional filters) |\n| Create lead | `KOMMO_CREATE_LEAD` | `name` |\n| Update lead | `KOMMO_UPDATE_LEAD` | Lead ID |\n| Create task | `KOMMO_CREATE_TASK` | Task details |\n| List custom fields | `KOMMO_LIST_CUSTOM_FIELDS` | Entity type |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kontent-ai-automation/SKILL.md",
    "content": "---\nname: kontent-ai-automation\ndescription: \"Automate Kontent AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kontent AI Automation via Rube MCP\n\nAutomate Kontent AI operations through Composio's Kontent AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kontent_ai](https://composio.dev/toolkits/kontent_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kontent AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kontent_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kontent_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kontent AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kontent AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kontent_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kontent AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kontent_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/kraken-io-automation/SKILL.md",
    "content": "---\nname: kraken-io-automation\ndescription: \"Automate Kraken IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Kraken IO Automation via Rube MCP\n\nAutomate Kraken IO operations through Composio's Kraken IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/kraken_io](https://composio.dev/toolkits/kraken_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Kraken IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `kraken_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `kraken_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Kraken IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Kraken IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"kraken_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Kraken IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `kraken_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/l2s-automation/SKILL.md",
    "content": "---\nname: l2s-automation\ndescription: \"Automate L2s tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# L2s Automation via Rube MCP\n\nAutomate L2s operations through Composio's L2s toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/l2s](https://composio.dev/toolkits/l2s)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active L2s connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `l2s`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `l2s`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"L2s operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific L2s task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"l2s\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with L2s-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `l2s` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/labs64-netlicensing-automation/SKILL.md",
    "content": "---\nname: labs64-netlicensing-automation\ndescription: \"Automate Labs64 Netlicensing tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Labs64 Netlicensing Automation via Rube MCP\n\nAutomate Labs64 Netlicensing operations through Composio's Labs64 Netlicensing toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/labs64_netlicensing](https://composio.dev/toolkits/labs64_netlicensing)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Labs64 Netlicensing connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `labs64_netlicensing`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `labs64_netlicensing`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Labs64 Netlicensing operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Labs64 Netlicensing task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"labs64_netlicensing\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Labs64 Netlicensing-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `labs64_netlicensing` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/landbot-automation/SKILL.md",
    "content": "---\nname: landbot-automation\ndescription: \"Automate Landbot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Landbot Automation via Rube MCP\n\nAutomate Landbot operations through Composio's Landbot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/landbot](https://composio.dev/toolkits/landbot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Landbot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `landbot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `landbot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Landbot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Landbot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"landbot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Landbot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `landbot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/langbase-automation/SKILL.md",
    "content": "---\nname: langbase-automation\ndescription: \"Automate Langbase tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Langbase Automation via Rube MCP\n\nAutomate Langbase operations through Composio's Langbase toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/langbase](https://composio.dev/toolkits/langbase)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Langbase connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `langbase`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `langbase`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Langbase operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Langbase task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"langbase\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Langbase-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `langbase` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lastpass-automation/SKILL.md",
    "content": "---\nname: lastpass-automation\ndescription: \"Automate Lastpass tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lastpass Automation via Rube MCP\n\nAutomate Lastpass operations through Composio's Lastpass toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lastpass](https://composio.dev/toolkits/lastpass)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lastpass connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lastpass`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lastpass`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lastpass operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lastpass task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lastpass\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lastpass-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lastpass` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/launch-darkly-automation/SKILL.md",
    "content": "---\nname: LaunchDarkly Automation\ndescription: \"Automate LaunchDarkly feature flag management -- list projects and environments, create and delete trigger workflows, and track code references via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# LaunchDarkly Automation\n\nAutomate your LaunchDarkly feature flag workflows -- enumerate projects and environments, create webhook-driven flag triggers, manage trigger lifecycle, and audit code references across repositories.\n\n**Toolkit docs:** [composio.dev/toolkits/launch_darkly](https://composio.dev/toolkits/launch_darkly)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your LaunchDarkly account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List Projects\n\nUse `LAUNCH_DARKLY_LIST_PROJECTS` to discover all projects and their keys for subsequent operations.\n\n```\nTool: LAUNCH_DARKLY_LIST_PROJECTS\nInputs:\n  - filter: string (e.g., \"query:myproject\" or \"keys:proj1,proj2\" or \"tags:mytag\")\n  - expand: string (e.g., \"environments\" to include env list per project)\n  - limit: integer (default 20)\n  - offset: integer (pagination start index)\n  - sort: string (e.g., \"name\" or \"-name\" for descending)\n```\n\n### 2. Get Environments for a Project\n\nUse `LAUNCH_DARKLY_GET_ENVIRONMENTS` to list all environments within a project (production, staging, test, etc.).\n\n```\nTool: LAUNCH_DARKLY_GET_ENVIRONMENTS\nInputs:\n  - project_key: string (required) -- e.g., \"my-project\", \"default\"\n  - filter: string (e.g., \"query:production\")\n  - limit: integer (default 20)\n  - offset: integer (pagination)\n  - sort: string (e.g., \"name\" or \"-name\")\n```\n\n### 3. Create a Flag Trigger Workflow\n\nUse `LAUNCH_DARKLY_CREATE_TRIGGER_WORKFLOW` to set up automated flag toggles triggered by external events (webhooks, Datadog alerts, etc.).\n\n```\nTool: LAUNCH_DARKLY_CREATE_TRIGGER_WORKFLOW\nInputs:\n  - project_key: string (required)\n  - feature_flag_key: string (required) -- e.g., \"new-feature\", \"enable-dark-mode\"\n  - environment_key: string (required) -- e.g., \"production\", \"staging\"\n  - integration_key: string (default \"generic-trigger\") -- or \"datadog\", \"honeycomb\", \"dynatrace\"\n  - instructions: array of objects (optional):\n      - kind: \"flag_action\" (fixed)\n      - action: \"turnFlagOn\" | \"turnFlagOff\"\n  - comment: string (optional) -- description of the trigger purpose\n```\n\nThe trigger generates a unique webhook URL that can be called to execute the configured flag action.\n\n### 4. Delete a Flag Trigger Workflow\n\nUse `LAUNCH_DARKLY_DELETE_TRIGGER_WORKFLOW` to permanently remove a trigger and its URL.\n\n```\nTool: LAUNCH_DARKLY_DELETE_TRIGGER_WORKFLOW\nInputs:\n  - project_key: string (required)\n  - feature_flag_key: string (required)\n  - environment_key: string (required)\n  - id: string (required) -- the trigger ID returned during creation\n```\n\n**Warning:** Deletion is irreversible. The trigger and its URL cannot be recovered.\n\n### 5. List Code Reference Repositories\n\nUse `LAUNCH_DARKLY_LIST_CODE_REFERENCE_REPOSITORIES` to track where feature flags are used in your codebase.\n\n```\nTool: LAUNCH_DARKLY_LIST_CODE_REFERENCE_REPOSITORIES\nInputs:\n  - projKey: string (optional) -- filter by project key\n  - flagKey: string (optional) -- filter by feature flag key\n  - withBranches: string (any value to include branch data)\n  - withReferencesForDefaultBranch: string (any value to include code refs for default branch)\n```\n\n**Note:** Code references is an Enterprise feature requiring `code-reference-repository` write permissions.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Project key discovery | Always use `LAUNCH_DARKLY_LIST_PROJECTS` first to find valid project keys before calling other tools. |\n| Environment key format | Environment keys are lowercase slugs (e.g., \"production\", \"test\"), not display names. |\n| Trigger deletion is permanent | Once deleted via `LAUNCH_DARKLY_DELETE_TRIGGER_WORKFLOW`, the trigger URL is unrecoverable. |\n| Enterprise-only code refs | `LAUNCH_DARKLY_LIST_CODE_REFERENCE_REPOSITORIES` requires Enterprise plan and write permissions. |\n| Trigger instructions format | Each instruction object requires `kind: \"flag_action\"` (fixed constant) and `action` as either `turnFlagOn` or `turnFlagOff`. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `LAUNCH_DARKLY_LIST_PROJECTS` | List all projects with filtering and pagination |\n| `LAUNCH_DARKLY_GET_ENVIRONMENTS` | List environments within a project |\n| `LAUNCH_DARKLY_CREATE_TRIGGER_WORKFLOW` | Create a webhook-driven flag trigger |\n| `LAUNCH_DARKLY_DELETE_TRIGGER_WORKFLOW` | Permanently delete a flag trigger |\n| `LAUNCH_DARKLY_LIST_CODE_REFERENCE_REPOSITORIES` | List repos with code references to flags |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/launch_darkly-automation/SKILL.md",
    "content": "---\nname: launch_darkly-automation\ndescription: \"Automate LaunchDarkly tasks via Rube MCP (Composio): feature flags, environments, segments, and rollout management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# LaunchDarkly Automation via Rube MCP\n\nAutomate LaunchDarkly operations through Composio's LaunchDarkly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/launch_darkly](https://composio.dev/toolkits/launch_darkly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active LaunchDarkly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `launch_darkly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `launch_darkly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"feature flags, environments, segments, and rollout management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for LaunchDarkly\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available LaunchDarkly Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available LaunchDarkly tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute LaunchDarkly Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple LaunchDarkly operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the LaunchDarkly connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with LaunchDarkly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `launch_darkly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/launch_darkly](https://composio.dev/toolkits/launch_darkly)\n"
  },
  {
    "path": "composio-skills/leadfeeder-automation/SKILL.md",
    "content": "---\nname: leadfeeder-automation\ndescription: \"Automate Leadfeeder tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Leadfeeder Automation via Rube MCP\n\nAutomate Leadfeeder operations through Composio's Leadfeeder toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/leadfeeder](https://composio.dev/toolkits/leadfeeder)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Leadfeeder connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `leadfeeder`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `leadfeeder`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Leadfeeder operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Leadfeeder task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"leadfeeder\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Leadfeeder-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `leadfeeder` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/leadoku-automation/SKILL.md",
    "content": "---\nname: leadoku-automation\ndescription: \"Automate Leadoku tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Leadoku Automation via Rube MCP\n\nAutomate Leadoku operations through Composio's Leadoku toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/leadoku](https://composio.dev/toolkits/leadoku)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Leadoku connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `leadoku`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `leadoku`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Leadoku operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Leadoku task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"leadoku\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Leadoku-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `leadoku` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/leiga-automation/SKILL.md",
    "content": "---\nname: leiga-automation\ndescription: \"Automate Leiga tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Leiga Automation via Rube MCP\n\nAutomate Leiga operations through Composio's Leiga toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/leiga](https://composio.dev/toolkits/leiga)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Leiga connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `leiga`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `leiga`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Leiga operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Leiga task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"leiga\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Leiga-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `leiga` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lemlist-automation/SKILL.md",
    "content": "---\nname: Lemlist Automation\ndescription: \"Automate Lemlist multichannel outreach -- manage campaigns, enroll leads, add personalization variables, export campaign data, and handle unsubscribes via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Lemlist Automation\n\nAutomate your Lemlist multichannel outreach workflows -- manage campaigns, enroll leads at scale, enrich with custom variables, export campaign data, and clean up unsubscribes.\n\n**Toolkit docs:** [composio.dev/toolkits/lemlist](https://composio.dev/toolkits/lemlist)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Lemlist account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List and Discover Campaigns\n\nUse `LEMLIST_GET_LIST_CAMPAIGNS` to enumerate all campaigns by status, with pagination support.\n\n```\nTool: LEMLIST_GET_LIST_CAMPAIGNS\nInputs:\n  - status: \"running\" | \"draft\" | \"archived\" | \"ended\" | \"paused\" | \"errors\" (optional)\n  - limit: integer (max 100, default 100)\n  - offset: integer (pagination offset)\n  - sortBy: \"createdAt\"\n  - sortOrder: \"asc\" | \"desc\"\n```\n\n**Important:** The response may be wrapped as `{campaigns: [...], pagination: {...}}` instead of a flat list. Always extract from the `campaigns` key.\n\n### 2. Get Campaign Details\n\nUse `LEMLIST_GET_CAMPAIGN_BY_ID` to validate campaign configuration before writes.\n\n```\nTool: LEMLIST_GET_CAMPAIGN_BY_ID\nInputs:\n  - campaignId: string (required) -- e.g., \"cam_A1B2C3D4E5F6G7H8I9\"\n```\n\n### 3. Enroll Leads into a Campaign\n\nUse `LEMLIST_POST_CREATE_LEAD_IN_CAMPAIGN` to add leads with optional email finding, phone lookup, and LinkedIn enrichment.\n\n```\nTool: LEMLIST_POST_CREATE_LEAD_IN_CAMPAIGN\nInputs:\n  - campaignId: string (required)\n  - email: string (required)\n  - firstName, lastName, companyName, companyDomain: string (optional)\n  - jobTitle, phone, linkedinUrl, icebreaker: string (optional)\n  - deduplicate: boolean (prevents cross-campaign duplicates)\n  - findEmail, findPhone, verifyEmail, linkedinEnrichment: boolean (optional)\n  - timezone: string (IANA format, e.g., \"America/New_York\")\n```\n\n**Bulk pattern:** Chunk leads into batches of ~50 and checkpoint progress between batches.\n\n### 4. Add Custom Variables to a Lead\n\nUse `LEMLIST_POST_ADD_VARIABLES_TO_LEAD` to enrich leads with personalization fields after enrollment.\n\n```\nTool: LEMLIST_POST_ADD_VARIABLES_TO_LEAD\nInputs:\n  - leadId: string (required) -- internal Lemlist lead ID (NOT email)\n  - company: string (required) -- must match your company name in Lemlist\n  - variables: object (required) -- key-value pairs, e.g., {\"score\": \"42\", \"color\": \"yellow\"}\n```\n\n**Important:** This is NOT an upsert -- attempting to add variables that already exist will fail. Resolve the internal `leadId` via `LEMLIST_GET_RETRIEVE_LEAD_BY_EMAIL` if you only have the email address.\n\n### 5. Export Campaign Leads\n\nUse `LEMLIST_GET_EXPORT_CAMPAIGN_LEADS` to download leads with state filtering for reporting or QA.\n\n```\nTool: LEMLIST_GET_EXPORT_CAMPAIGN_LEADS\nInputs:\n  - campaignId: string (required)\n  - (supports state filtering and JSON/CSV output)\n```\n\n### 6. Unsubscribe Lead from Campaign\n\nUse `LEMLIST_DELETE_UNSUBSCRIBE_LEAD_FROM_CAMPAIGN` to stop outreach by removing a lead from a campaign.\n\n```\nTool: LEMLIST_DELETE_UNSUBSCRIBE_LEAD_FROM_CAMPAIGN\nInputs:\n  - campaignId: string (required)\n  - leadId or email: string (required)\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Wrapped campaign list | `LEMLIST_GET_LIST_CAMPAIGNS` may return `{campaigns: [...], pagination: {...}}` instead of a flat array. Always extract from the `campaigns` key. |\n| Cross-campaign deduplication | `LEMLIST_POST_CREATE_LEAD_IN_CAMPAIGN` with deduplication enabled fails with HTTP 500 \"Lead already in other campaign\" -- disable deduplication for intentional cross-campaign enrollment. |\n| Bulk import failures | Chunk bulk imports to ~50 per batch with checkpoints to avoid losing partial progress on intermittent failures. |\n| Invalid leadId | `LEMLIST_POST_ADD_VARIABLES_TO_LEAD` returns HTTP 400 \"Invalid leadId\" when using an email as the leadId -- resolve the internal ID via `LEMLIST_GET_RETRIEVE_LEAD_BY_EMAIL` first. |\n| Variable collisions | `LEMLIST_POST_ADD_VARIABLES_TO_LEAD` is not an upsert. Adding keys that already exist returns HTTP 400 \"Variables X already exist\". |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `LEMLIST_GET_LIST_CAMPAIGNS` | List all campaigns with status filter and pagination |\n| `LEMLIST_GET_CAMPAIGN_BY_ID` | Get detailed campaign info by ID |\n| `LEMLIST_POST_CREATE_LEAD_IN_CAMPAIGN` | Create and enroll a lead into a campaign |\n| `LEMLIST_POST_ADD_VARIABLES_TO_LEAD` | Add custom personalization variables to a lead |\n| `LEMLIST_GET_RETRIEVE_LEAD_BY_EMAIL` | Look up a lead by email address |\n| `LEMLIST_GET_EXPORT_CAMPAIGN_LEADS` | Export leads from a campaign with state filtering |\n| `LEMLIST_DELETE_UNSUBSCRIBE_LEAD_FROM_CAMPAIGN` | Remove a lead from a campaign |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lemon-squeezy-automation/SKILL.md",
    "content": "---\nname: Lemon Squeezy Automation\ndescription: \"Automate Lemon Squeezy store management -- products, orders, subscriptions, customers, discounts, and checkout tracking -- using natural language through the Composio MCP integration.\"\ncategory: e-commerce\nrequires:\n  mcp:\n    - rube\n---\n\n# Lemon Squeezy Automation\n\nManage your Lemon Squeezy digital products business -- track orders, monitor subscriptions, analyze customers, review discounts, and audit checkouts -- all through natural language commands.\n\n**Toolkit docs:** [composio.dev/toolkits/lemon_squeezy](https://composio.dev/toolkits/lemon_squeezy)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Lemon Squeezy account when prompted (API key authentication).\n3. Start issuing natural language commands to manage your store.\n\n---\n\n## Core Workflows\n\n### 1. Discover Stores and Products\nList all stores to get store IDs, then retrieve products and variants for a specific store.\n\n**Tools:** `LEMON_SQUEEZY_LIST_ALL_STORES`, `LEMON_SQUEEZY_LIST_ALL_PRODUCTS`, `LEMON_SQUEEZY_LIST_ALL_VARIANTS`\n\n**Example prompt:**\n> \"List all my Lemon Squeezy stores and their products\"\n\n**Key parameters:**\n- `LEMON_SQUEEZY_LIST_ALL_STORES` -- No parameters required\n- `LEMON_SQUEEZY_LIST_ALL_PRODUCTS` -- Filter by `filter[store_id]`\n- `LEMON_SQUEEZY_LIST_ALL_VARIANTS` -- Filter by `filter[product_id]`, `filter[status]` (pending/draft/published)\n\n---\n\n### 2. Track Orders and Order Items\nRetrieve all orders with optional filtering by store, user email, or order number, and drill into individual order items.\n\n**Tools:** `LEMON_SQUEEZY_LIST_ALL_ORDERS`, `LEMON_SQUEEZY_LIST_ALL_ORDER_ITEMS`\n\n**Example prompt:**\n> \"Show all orders from johndoe@example.com in my Lemon Squeezy store\"\n\n**Key parameters for orders:**\n- `filter[store_id]` -- Filter by store ID\n- `filter[user_email]` -- Filter by customer email\n- `filter[order_number]` -- Filter by specific order number\n- `page[number]` / `page[size]` -- Pagination (max 100 per page)\n\n**Key parameters for order items:**\n- `filter[order_id]`, `filter[product_id]`, `filter[variant_id]` -- Filter by related entity\n\n---\n\n### 3. Monitor Subscriptions\nList all subscriptions with rich filtering options to track recurring revenue.\n\n**Tool:** `LEMON_SQUEEZY_LIST_ALL_SUBSCRIPTIONS`\n\n**Example prompt:**\n> \"Show all active subscriptions in my Lemon Squeezy store\"\n\n**Key parameters:**\n- `filter[status]` -- Filter by status (e.g., `active`, `cancelled`)\n- `filter[store_id]` -- Filter by store\n- `filter[product_id]` -- Filter by product\n- `filter[user_email]` -- Filter by subscriber email\n- `filter[variant_id]` -- Filter by variant\n- `page[number]` / `page[size]` -- Pagination (max 100 per page)\n\n---\n\n### 4. Manage Customers\nRetrieve customer records with details including email, MRR, total revenue, and customer portal URLs.\n\n**Tool:** `LEMON_SQUEEZY_LIST_ALL_CUSTOMERS`\n\n**Example prompt:**\n> \"Find the Lemon Squeezy customer with email johndoe@example.com\"\n\n**Key parameters:**\n- `filter[email]` -- Filter by exact email address\n- `filter[store_id]` -- Filter by store ID\n- `page[number]` / `page[size]` -- Pagination (max 100 per page)\n\n---\n\n### 5. Audit Discounts and Redemptions\nList all discount codes and track how they have been redeemed across orders.\n\n**Tools:** `LEMON_SQUEEZY_LIST_ALL_DISCOUNTS`, `LEMON_SQUEEZY_LIST_ALL_DISCOUNT_REDEMPTIONS`\n\n**Example prompt:**\n> \"Show all discounts for store 12345 and their redemption history\"\n\n**Key parameters for discounts:**\n- `filter[store_id]` -- Filter by store\n- `page[number]` / `page[size]` -- Pagination\n\n**Key parameters for redemptions:**\n- `filter[discount_id]` -- Filter by discount\n- `filter[order_id]` -- Filter by order\n\n---\n\n### 6. Review Checkouts\nList all checkout sessions with optional filtering by store or variant.\n\n**Tool:** `LEMON_SQUEEZY_LIST_ALL_CHECKOUTS`\n\n**Example prompt:**\n> \"Show all checkouts for variant 42 in my Lemon Squeezy store\"\n\n**Key parameters:**\n- `filter[store_id]` -- Filter by store ID\n- `filter[variant_id]` -- Filter by variant ID\n\n---\n\n## Known Pitfalls\n\n- **Store ID is foundational**: Most filters require a `store_id`. Always call `LEMON_SQUEEZY_LIST_ALL_STORES` first to discover valid store IDs before filtering other resources.\n- **Pagination is mandatory for large datasets**: All list endpoints use `page[number]` / `page[size]` pagination (max 100 per page). Do not assume the first page is complete.\n- **Filter parameter naming**: Lemon Squeezy uses bracket notation for filters (e.g., `filter[store_id]`, `page[number]`). Ensure exact parameter names are used.\n- **Subscription invoices vs. orders**: Subscription invoices (`LEMON_SQUEEZY_LIST_ALL_SUBSCRIPTION_INVOICES`) are separate from one-time orders. Use the appropriate endpoint for your use case.\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Required Params |\n|---|---|---|\n| List stores | `LEMON_SQUEEZY_LIST_ALL_STORES` | None |\n| List products | `LEMON_SQUEEZY_LIST_ALL_PRODUCTS` | None (optional filters) |\n| List variants | `LEMON_SQUEEZY_LIST_ALL_VARIANTS` | None (optional filters) |\n| List orders | `LEMON_SQUEEZY_LIST_ALL_ORDERS` | None (optional filters) |\n| List order items | `LEMON_SQUEEZY_LIST_ALL_ORDER_ITEMS` | None (optional filters) |\n| List subscriptions | `LEMON_SQUEEZY_LIST_ALL_SUBSCRIPTIONS` | None (optional filters) |\n| List customers | `LEMON_SQUEEZY_LIST_ALL_CUSTOMERS` | None (optional filters) |\n| List discounts | `LEMON_SQUEEZY_LIST_ALL_DISCOUNTS` | None (optional filters) |\n| List discount redemptions | `LEMON_SQUEEZY_LIST_ALL_DISCOUNT_REDEMPTIONS` | None (optional filters) |\n| List checkouts | `LEMON_SQUEEZY_LIST_ALL_CHECKOUTS` | None (optional filters) |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lemon_squeezy-automation/SKILL.md",
    "content": "---\nname: lemon_squeezy-automation\ndescription: \"Automate Lemon Squeezy tasks via Rube MCP (Composio): products, orders, subscriptions, checkouts, and digital sales. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lemon Squeezy Automation via Rube MCP\n\nAutomate Lemon Squeezy operations through Composio's Lemon Squeezy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lemon_squeezy](https://composio.dev/toolkits/lemon_squeezy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lemon Squeezy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lemon_squeezy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lemon_squeezy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"products, orders, subscriptions, checkouts, and digital sales\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Lemon Squeezy\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Lemon Squeezy Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Lemon Squeezy tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Lemon Squeezy Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Lemon Squeezy operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Lemon Squeezy connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lemon Squeezy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lemon_squeezy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/lemon_squeezy](https://composio.dev/toolkits/lemon_squeezy)\n"
  },
  {
    "path": "composio-skills/lessonspace-automation/SKILL.md",
    "content": "---\nname: lessonspace-automation\ndescription: \"Automate Lessonspace tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lessonspace Automation via Rube MCP\n\nAutomate Lessonspace operations through Composio's Lessonspace toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lessonspace](https://composio.dev/toolkits/lessonspace)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lessonspace connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lessonspace`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lessonspace`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lessonspace operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lessonspace task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lessonspace\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lessonspace-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lessonspace` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lever-automation/SKILL.md",
    "content": "---\nname: Lever Automation\ndescription: \"Automate recruiting workflows in Lever ATS -- manage opportunities, job postings, requisitions, pipeline stages, and candidate tags through the Composio Lever integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Lever Automation\n\nAutomate your recruiting operations in **Lever ATS** directly from Claude Code. Manage job postings, track candidate pipelines, update requisitions, and query opportunities without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/lever](https://composio.dev/toolkits/lever)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Lever account when prompted by running any Lever command. The agent will provide an OAuth link to authenticate.\n3. Ensure your Lever API key has sufficient scopes for the operations you need (read/write access to postings, opportunities, requisitions).\n\n---\n\n## Core Workflows\n\n### 1. List and Filter Job Postings\n\nRetrieve all job postings with optional filtering by state, team, department, location, or commitment type.\n\n**Tool:** `LEVER_LIST_POSTINGS`\n\nKey parameters:\n- `state` -- filter by `published`, `internal`, `closed`, `draft`, `pending`, `rejected`\n- `team`, `department`, `location`, `commitment` -- narrow results by organizational attributes\n- `limit` (1-100) and `offset` -- paginate through large posting sets\n- `tag` -- filter by posting tag\n\nExample prompt: *\"List all published engineering job postings in Lever\"*\n\n---\n\n### 2. Browse Candidate Opportunities\n\nList all opportunities in the hiring pipeline with rich filtering for pipeline analysis and candidate tracking.\n\n**Tool:** `LEVER_LIST_OPPORTUNITIES`\n\nKey parameters:\n- `posting_id`, `stage_id`, `tag` -- filter by posting, pipeline stage, or tag\n- `email`, `contact_id` -- find opportunities for a specific candidate\n- `archived` -- filter by archived status (`true`/`false`)\n- `created_at_start`, `created_at_end` -- date range filtering (ISO 8601)\n- `expand` -- expand `applications`, `contact`, `owner`, `stage`, `stageChanges`, `sources`, `sourcedBy` into full objects\n\nExample prompt: *\"Show me all active opportunities for the Senior Engineer posting, expanded with contact details\"*\n\n---\n\n### 3. Get Opportunity Details\n\nFetch comprehensive details about a single candidate opportunity including contact info, stage progression, sources, and applications.\n\n**Tool:** `LEVER_GET_OPPORTUNITY`\n\nKey parameters:\n- `opportunity` (required) -- the unique opportunity UID\n- `expand` -- comma-separated fields to expand: `contact`, `stage`, `owner`\n\nExample prompt: *\"Get full details for opportunity 31c9716c-d4e3-47e8-a6a1-54078a1151d6 with contact and stage expanded\"*\n\n---\n\n### 4. Manage Requisitions\n\nCreate, list, update, and delete requisitions to track headcount and hiring needs.\n\n**Tools:** `LEVER_LIST_REQUISITIONS`, `LEVER_GET_REQUISITION`, `LEVER_UPDATE_REQUISITION`, `LEVER_DELETE_REQUISITION`\n\nUpdate requires these fields:\n- `requisition` (required) -- UUID of the requisition\n- `requisitionCode` (required) -- unique code like `REQ-001`\n- `name` (required) -- requisition title\n- `headcountTotal` (required) -- number of positions (minimum 1)\n- `status` -- `open` or `closed`\n- Optional: `hiringManager`, `owner`, `department`, `team`, `location`, `compensationBand`\n\nExample prompt: *\"Update requisition REQ-001 to increase headcount to 3 and change status to open\"*\n\n---\n\n### 5. View Pipeline Stages\n\nRetrieve all hiring pipeline stages configured in your Lever account.\n\n**Tool:** `LEVER_LIST_STAGES`\n\nKey parameters:\n- `limit` (1-100) -- max items per page\n- `offset` -- pagination token from previous response\n\nExample prompt: *\"List all pipeline stages in our Lever account\"*\n\n---\n\n### 6. Manage Tags\n\nList all tags used to categorize candidates, opportunities, and postings.\n\n**Tool:** `LEVER_LIST_TAGS`\n\nKey parameters:\n- `limit` -- max items per page\n- `offset` -- pagination token\n\nExample prompt: *\"Show all candidate tags in Lever\"*\n\n---\n\n## Known Pitfalls\n\n- **Pagination required for large datasets:** `LEVER_LIST_OPPORTUNITIES` and `LEVER_LIST_POSTINGS` default to 100 results max per page. Always check for an `offset` token in the response and iterate to get complete results.\n- **Expand parameter format:** The `expand` field on `LEVER_LIST_OPPORTUNITIES` accepts an array of strings, while on `LEVER_GET_OPPORTUNITY` and `LEVER_GET_REQUISITION` it accepts a comma-separated string. Follow the exact schema for each tool.\n- **Requisition updates are full replacements:** `LEVER_UPDATE_REQUISITION` requires all mandatory fields (`requisitionCode`, `name`, `headcountTotal`) even if you only want to change one field. Always fetch the current requisition first with `LEVER_GET_REQUISITION`.\n- **Timestamps:** Opportunity date filters use ISO 8601 format, while `LEVER_LIST_POSTINGS` uses Unix timestamps in milliseconds for `updated_at_start`.\n- **Connection scopes:** Write operations (update/delete requisitions) will fail if your API token lacks the necessary permissions, even if reads succeed.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `LEVER_LIST_POSTINGS` | List all job postings with filtering by state, team, department |\n| `LEVER_LIST_OPPORTUNITIES` | List candidate opportunities with pipeline filtering |\n| `LEVER_GET_OPPORTUNITY` | Get detailed info for a single opportunity |\n| `LEVER_GET_REQUISITION` | Retrieve a single requisition by ID |\n| `LEVER_LIST_REQUISITIONS` | List all requisitions with status/code filtering |\n| `LEVER_UPDATE_REQUISITION` | Update an existing requisition (full replacement) |\n| `LEVER_DELETE_REQUISITION` | Delete/archive a requisition |\n| `LEVER_LIST_STAGES` | List all pipeline stages |\n| `LEVER_LIST_TAGS` | List all tags for categorization |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lever-sandbox-automation/SKILL.md",
    "content": "---\nname: lever-sandbox-automation\ndescription: \"Automate Lever Sandbox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lever Sandbox Automation via Rube MCP\n\nAutomate Lever Sandbox operations through Composio's Lever Sandbox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lever_sandbox](https://composio.dev/toolkits/lever_sandbox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lever Sandbox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lever_sandbox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lever_sandbox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lever Sandbox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lever Sandbox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lever_sandbox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lever Sandbox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lever_sandbox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/leverly-automation/SKILL.md",
    "content": "---\nname: leverly-automation\ndescription: \"Automate Leverly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Leverly Automation via Rube MCP\n\nAutomate Leverly operations through Composio's Leverly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/leverly](https://composio.dev/toolkits/leverly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Leverly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `leverly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `leverly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Leverly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Leverly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"leverly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Leverly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `leverly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lexoffice-automation/SKILL.md",
    "content": "---\nname: lexoffice-automation\ndescription: \"Automate Lexoffice tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lexoffice Automation via Rube MCP\n\nAutomate Lexoffice operations through Composio's Lexoffice toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lexoffice](https://composio.dev/toolkits/lexoffice)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lexoffice connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lexoffice`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lexoffice`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lexoffice operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lexoffice task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lexoffice\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lexoffice-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lexoffice` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/linguapop-automation/SKILL.md",
    "content": "---\nname: linguapop-automation\ndescription: \"Automate Linguapop tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Linguapop Automation via Rube MCP\n\nAutomate Linguapop operations through Composio's Linguapop toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/linguapop](https://composio.dev/toolkits/linguapop)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Linguapop connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `linguapop`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `linguapop`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Linguapop operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Linguapop task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"linguapop\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Linguapop-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `linguapop` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/linkhut-automation/SKILL.md",
    "content": "---\nname: linkhut-automation\ndescription: \"Automate Linkhut tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Linkhut Automation via Rube MCP\n\nAutomate Linkhut operations through Composio's Linkhut toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/linkhut](https://composio.dev/toolkits/linkhut)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Linkhut connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `linkhut`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `linkhut`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Linkhut operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Linkhut task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"linkhut\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Linkhut-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `linkhut` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/linkup-automation/SKILL.md",
    "content": "---\nname: linkup-automation\ndescription: \"Automate Linkup tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Linkup Automation via Rube MCP\n\nAutomate Linkup operations through Composio's Linkup toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/linkup](https://composio.dev/toolkits/linkup)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Linkup connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `linkup`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `linkup`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Linkup operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Linkup task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"linkup\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Linkup-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `linkup` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/listclean-automation/SKILL.md",
    "content": "---\nname: listclean-automation\ndescription: \"Automate Listclean tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Listclean Automation via Rube MCP\n\nAutomate Listclean operations through Composio's Listclean toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/listclean](https://composio.dev/toolkits/listclean)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Listclean connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `listclean`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `listclean`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Listclean operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Listclean task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"listclean\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Listclean-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `listclean` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/listennotes-automation/SKILL.md",
    "content": "---\nname: listennotes-automation\ndescription: \"Automate Listennotes tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Listennotes Automation via Rube MCP\n\nAutomate Listennotes operations through Composio's Listennotes toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/listennotes](https://composio.dev/toolkits/listennotes)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Listennotes connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `listennotes`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `listennotes`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Listennotes operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Listennotes task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"listennotes\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Listennotes-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `listennotes` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/livesession-automation/SKILL.md",
    "content": "---\nname: livesession-automation\ndescription: \"Automate Livesession tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Livesession Automation via Rube MCP\n\nAutomate Livesession operations through Composio's Livesession toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/livesession](https://composio.dev/toolkits/livesession)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Livesession connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `livesession`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `livesession`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Livesession operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Livesession task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"livesession\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Livesession-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `livesession` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lmnt-automation/SKILL.md",
    "content": "---\nname: lmnt-automation\ndescription: \"Automate Lmnt tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lmnt Automation via Rube MCP\n\nAutomate Lmnt operations through Composio's Lmnt toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lmnt](https://composio.dev/toolkits/lmnt)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lmnt connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lmnt`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lmnt`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lmnt operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lmnt task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lmnt\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lmnt-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lmnt` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/lodgify-automation/SKILL.md",
    "content": "---\nname: lodgify-automation\ndescription: \"Automate Lodgify tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Lodgify Automation via Rube MCP\n\nAutomate Lodgify operations through Composio's Lodgify toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/lodgify](https://composio.dev/toolkits/lodgify)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Lodgify connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `lodgify`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `lodgify`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Lodgify operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Lodgify task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"lodgify\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Lodgify-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `lodgify` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/logo-dev-automation/SKILL.md",
    "content": "---\nname: logo-dev-automation\ndescription: \"Automate Logo Dev tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Logo Dev Automation via Rube MCP\n\nAutomate Logo Dev operations through Composio's Logo Dev toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/logo_dev](https://composio.dev/toolkits/logo_dev)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Logo Dev connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `logo_dev`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `logo_dev`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Logo Dev operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Logo Dev task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"logo_dev\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Logo Dev-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `logo_dev` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/loomio-automation/SKILL.md",
    "content": "---\nname: loomio-automation\ndescription: \"Automate Loomio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Loomio Automation via Rube MCP\n\nAutomate Loomio operations through Composio's Loomio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/loomio](https://composio.dev/toolkits/loomio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Loomio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `loomio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `loomio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Loomio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Loomio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"loomio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Loomio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `loomio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/loyverse-automation/SKILL.md",
    "content": "---\nname: loyverse-automation\ndescription: \"Automate Loyverse tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Loyverse Automation via Rube MCP\n\nAutomate Loyverse operations through Composio's Loyverse toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/loyverse](https://composio.dev/toolkits/loyverse)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Loyverse connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `loyverse`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `loyverse`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Loyverse operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Loyverse task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"loyverse\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Loyverse-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `loyverse` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/magnetic-automation/SKILL.md",
    "content": "---\nname: magnetic-automation\ndescription: \"Automate Magnetic tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Magnetic Automation via Rube MCP\n\nAutomate Magnetic operations through Composio's Magnetic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/magnetic](https://composio.dev/toolkits/magnetic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Magnetic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `magnetic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `magnetic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Magnetic operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Magnetic task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"magnetic\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Magnetic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `magnetic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailbluster-automation/SKILL.md",
    "content": "---\nname: mailbluster-automation\ndescription: \"Automate Mailbluster tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailbluster Automation via Rube MCP\n\nAutomate Mailbluster operations through Composio's Mailbluster toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailbluster](https://composio.dev/toolkits/mailbluster)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailbluster connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailbluster`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailbluster`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailbluster operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailbluster task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailbluster\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailbluster-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailbluster` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailboxlayer-automation/SKILL.md",
    "content": "---\nname: mailboxlayer-automation\ndescription: \"Automate Mailboxlayer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailboxlayer Automation via Rube MCP\n\nAutomate Mailboxlayer operations through Composio's Mailboxlayer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailboxlayer](https://composio.dev/toolkits/mailboxlayer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailboxlayer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailboxlayer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailboxlayer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailboxlayer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailboxlayer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailboxlayer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailboxlayer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailboxlayer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailcheck-automation/SKILL.md",
    "content": "---\nname: mailcheck-automation\ndescription: \"Automate Mailcheck tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailcheck Automation via Rube MCP\n\nAutomate Mailcheck operations through Composio's Mailcheck toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailcheck](https://composio.dev/toolkits/mailcheck)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailcheck connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcheck`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcheck`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailcheck operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailcheck task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailcheck\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailcheck-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcheck` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailcoach-automation/SKILL.md",
    "content": "---\nname: mailcoach-automation\ndescription: \"Automate Mailcoach tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailcoach Automation via Rube MCP\n\nAutomate Mailcoach operations through Composio's Mailcoach toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailcoach](https://composio.dev/toolkits/mailcoach)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailcoach connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcoach`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcoach`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailcoach operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailcoach task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailcoach\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailcoach-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailcoach` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailerlite-automation/SKILL.md",
    "content": "---\nname: MailerLite Automation\ndescription: \"Automate email marketing workflows including subscriber management, campaign analytics, group segmentation, and account monitoring through MailerLite via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# MailerLite Automation\n\nAutomate email marketing operations -- manage subscribers, analyze campaign performance, organize groups and segments, and monitor account health -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/mailerlite](https://composio.dev/toolkits/mailerlite)\n\n---\n\n## Setup\n\n1. Connect your MailerLite account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `MAILERLITE_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. Verify Account & Fetch Metadata\nRetrieve account details including plan limits and timezone to ensure consistent reporting.\n\n**Tool:** `MAILERLITE_GET_ACCOUNT_INFO`\n\n```\nNo parameters required -- returns account metadata, plan details, and timezone configuration.\n```\n\nAlways run this first to establish plan constraints and timezone for consistent time-windowed queries.\n\n---\n\n### 2. Get Account-Wide Performance Stats\nRetrieve aggregate subscriber counts, sent email totals, and engagement metrics for a health snapshot.\n\n**Tool:** `MAILERLITE_GET_ACCOUNT_STATS`\n\n```\nNo parameters required -- returns overall subscriber counts, sent emails, and performance metrics.\n```\n\n---\n\n### 3. List & Paginate Subscribers\nRetrieve subscribers with optional status filtering and cursor-based pagination.\n\n**Tool:** `MAILERLITE_GET_SUBSCRIBERS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `filter[status]` | string | No | Filter by: `active`, `unsubscribed`, `unconfirmed`, `bounced`, `junk` |\n| `limit` | integer | No | Subscribers per page (default: 25) |\n| `cursor` | string | No | Pagination cursor from previous response `meta.cursor` |\n| `include` | string | No | Set to `groups` to include group memberships |\n\n**Important:** Loop with `meta.next_cursor` until `null` to build a complete subscriber list.\n\n---\n\n### 4. List & Analyze Campaigns\nRetrieve campaigns with optional status/type filters and page-based pagination.\n\n**Tool:** `MAILERLITE_GET_CAMPAIGNS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `filter[status]` | string | No | Filter by: `sent`, `draft`, `ready` |\n| `filter[type]` | string | No | Filter by: `regular`, `ab`, `resend`, `rss` |\n| `limit` | integer | No | Items per page (default: 25) |\n| `page` | integer | No | Page number (default: 1) |\n\n**Important:** Paginate using `meta.last_page` to avoid omitting campaigns from historical analysis.\n\n---\n\n### 5. Manage Subscriber Groups\nList, filter, and sort subscriber groups for audience organization.\n\n**Tool:** `MAILERLITE_GET_GROUPS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `filter[name]` | string | No | Partial name match filter |\n| `limit` | integer | No | Max groups to return |\n| `page` | integer | No | Page number (starting from 1) |\n| `sort` | string | No | Sort by: `name`, `total`, `open_rate`, `click_rate`, `created_at` (prefix `-` for descending) |\n\n---\n\n### 6. Retrieve Audience Segments & Custom Fields\nFetch segments and custom field definitions for advanced audience analysis.\n\n**Tools:** `MAILERLITE_GET_SEGMENTS` and `MAILERLITE_GET_FIELDS`\n\n**Segments:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `limit` | integer | No | Max segments to return (max 250) |\n| `page` | integer | No | Page number (starting from 1) |\n\n**Fields:** No parameters required -- returns all custom field definitions.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Subscriber pagination is cursor-based** | `MAILERLITE_GET_SUBSCRIBERS` uses `meta.next_cursor` -- you must loop until `null` or counts will be incomplete |\n| **Campaign pagination is page-based** | `MAILERLITE_GET_CAMPAIGNS` uses `page`/`limit` with `meta.last_page` -- stopping early omits campaigns and distorts trends |\n| **Sampling bias** | Computing engagement metrics from only the first page introduces bias; always aggregate across all pages |\n| **Nested response shape** | MailerLite payloads are nested under `results[i].response.data` with `data` and `meta` subkeys, not a flat `data` key -- parse accordingly |\n| **API quotas** | Subscriber listing is limited by MailerLite Connect API quotas -- plan batch operations accordingly |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `MAILERLITE_GET_ACCOUNT_INFO` | Verify auth and review account metadata |\n| `MAILERLITE_GET_ACCOUNT_STATS` | Get aggregate performance metrics |\n| `MAILERLITE_GET_SUBSCRIBERS` | List subscribers with filtering and pagination |\n| `MAILERLITE_GET_CAMPAIGNS` | List campaigns with status/type filters |\n| `MAILERLITE_GET_GROUPS` | List and sort subscriber groups |\n| `MAILERLITE_GET_SEGMENTS` | List audience segments |\n| `MAILERLITE_GET_FIELDS` | Retrieve custom field definitions |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailersend-automation/SKILL.md",
    "content": "---\nname: mailersend-automation\ndescription: \"Automate Mailersend tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailersend Automation via Rube MCP\n\nAutomate Mailersend operations through Composio's Mailersend toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailersend](https://composio.dev/toolkits/mailersend)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailersend connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailersend`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailersend`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailersend operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailersend task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailersend\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailersend-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailersend` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mails-so-automation/SKILL.md",
    "content": "---\nname: mails-so-automation\ndescription: \"Automate Mails So tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mails So Automation via Rube MCP\n\nAutomate Mails So operations through Composio's Mails So toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mails_so](https://composio.dev/toolkits/mails_so)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mails So connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mails_so`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mails_so`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mails So operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mails So task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mails_so\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mails So-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mails_so` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mailsoftly-automation/SKILL.md",
    "content": "---\nname: mailsoftly-automation\ndescription: \"Automate Mailsoftly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mailsoftly Automation via Rube MCP\n\nAutomate Mailsoftly operations through Composio's Mailsoftly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mailsoftly](https://composio.dev/toolkits/mailsoftly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mailsoftly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mailsoftly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mailsoftly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mailsoftly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mailsoftly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mailsoftly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mailsoftly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mailsoftly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/maintainx-automation/SKILL.md",
    "content": "---\nname: maintainx-automation\ndescription: \"Automate Maintainx tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Maintainx Automation via Rube MCP\n\nAutomate Maintainx operations through Composio's Maintainx toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/maintainx](https://composio.dev/toolkits/maintainx)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Maintainx connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `maintainx`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `maintainx`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Maintainx operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Maintainx task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"maintainx\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Maintainx-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `maintainx` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/many-chat-automation/SKILL.md",
    "content": "---\nname: many-chat-automation\ndescription: \"Automate ManyChat tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# ManyChat Automation via Rube MCP\n\nAutomate ManyChat operations through Composio's ManyChat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/many_chat](https://composio.dev/toolkits/many_chat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active ManyChat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"ManyChat operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific ManyChat task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"many_chat\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with ManyChat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/many_chat-automation/SKILL.md",
    "content": "---\nname: many_chat-automation\ndescription: \"Automate ManyChat tasks via Rube MCP (Composio): chatbot flows, subscribers, broadcasts, and messenger automation. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# ManyChat Automation via Rube MCP\n\nAutomate ManyChat operations through Composio's ManyChat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/many_chat](https://composio.dev/toolkits/many_chat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active ManyChat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"chatbot flows, subscribers, broadcasts, and messenger automation\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for ManyChat\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available ManyChat Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available ManyChat tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute ManyChat Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple ManyChat operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the ManyChat connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with ManyChat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `many_chat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/many_chat](https://composio.dev/toolkits/many_chat)\n"
  },
  {
    "path": "composio-skills/mapbox-automation/SKILL.md",
    "content": "---\nname: mapbox-automation\ndescription: \"Automate Mapbox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mapbox Automation via Rube MCP\n\nAutomate Mapbox operations through Composio's Mapbox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mapbox](https://composio.dev/toolkits/mapbox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mapbox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mapbox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mapbox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mapbox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mapbox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mapbox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mapbox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mapbox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mapulus-automation/SKILL.md",
    "content": "---\nname: mapulus-automation\ndescription: \"Automate Mapulus tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mapulus Automation via Rube MCP\n\nAutomate Mapulus operations through Composio's Mapulus toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mapulus](https://composio.dev/toolkits/mapulus)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mapulus connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mapulus`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mapulus`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mapulus operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mapulus task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mapulus\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mapulus-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mapulus` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mboum-automation/SKILL.md",
    "content": "---\nname: mboum-automation\ndescription: \"Automate Mboum tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mboum Automation via Rube MCP\n\nAutomate Mboum operations through Composio's Mboum toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mboum](https://composio.dev/toolkits/mboum)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mboum connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mboum`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mboum`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mboum operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mboum task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mboum\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mboum-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mboum` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/melo-automation/SKILL.md",
    "content": "---\nname: melo-automation\ndescription: \"Automate Melo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Melo Automation via Rube MCP\n\nAutomate Melo operations through Composio's Melo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/melo](https://composio.dev/toolkits/melo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Melo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `melo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `melo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Melo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Melo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"melo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Melo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `melo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mem-automation/SKILL.md",
    "content": "---\nname: mem-automation\ndescription: \"Automate Mem tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mem Automation via Rube MCP\n\nAutomate Mem operations through Composio's Mem toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mem](https://composio.dev/toolkits/mem)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mem connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mem`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mem`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mem operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mem task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mem\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mem-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mem` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mem0-automation/SKILL.md",
    "content": "---\nname: mem0-automation\ndescription: \"Automate Mem0 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mem0 Automation via Rube MCP\n\nAutomate Mem0 operations through Composio's Mem0 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mem0](https://composio.dev/toolkits/mem0)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mem0 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mem0`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mem0`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mem0 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mem0 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mem0\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mem0-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mem0` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/memberspot-automation/SKILL.md",
    "content": "---\nname: memberspot-automation\ndescription: \"Automate Memberspot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Memberspot Automation via Rube MCP\n\nAutomate Memberspot operations through Composio's Memberspot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/memberspot](https://composio.dev/toolkits/memberspot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Memberspot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `memberspot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `memberspot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Memberspot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Memberspot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"memberspot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Memberspot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `memberspot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/memberstack-automation/SKILL.md",
    "content": "---\nname: memberstack-automation\ndescription: \"Automate Memberstack tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Memberstack Automation via Rube MCP\n\nAutomate Memberstack operations through Composio's Memberstack toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/memberstack](https://composio.dev/toolkits/memberstack)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Memberstack connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `memberstack`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `memberstack`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Memberstack operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Memberstack task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"memberstack\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Memberstack-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `memberstack` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/membervault-automation/SKILL.md",
    "content": "---\nname: membervault-automation\ndescription: \"Automate Membervault tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Membervault Automation via Rube MCP\n\nAutomate Membervault operations through Composio's Membervault toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/membervault](https://composio.dev/toolkits/membervault)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Membervault connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `membervault`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `membervault`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Membervault operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Membervault task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"membervault\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Membervault-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `membervault` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/metaads-automation/SKILL.md",
    "content": "---\nname: metaads-automation\ndescription: \"Automate Metaads tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Metaads Automation via Rube MCP\n\nAutomate Metaads operations through Composio's Metaads toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/metaads](https://composio.dev/toolkits/metaads)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Metaads connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `metaads`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `metaads`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Metaads operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Metaads task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"metaads\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Metaads-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `metaads` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/metaphor-automation/SKILL.md",
    "content": "---\nname: metaphor-automation\ndescription: \"Automate Metaphor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Metaphor Automation via Rube MCP\n\nAutomate Metaphor operations through Composio's Metaphor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/metaphor](https://composio.dev/toolkits/metaphor)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Metaphor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `metaphor`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `metaphor`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Metaphor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Metaphor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"metaphor\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Metaphor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `metaphor` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mezmo-automation/SKILL.md",
    "content": "---\nname: mezmo-automation\ndescription: \"Automate Mezmo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mezmo Automation via Rube MCP\n\nAutomate Mezmo operations through Composio's Mezmo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mezmo](https://composio.dev/toolkits/mezmo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mezmo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mezmo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mezmo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mezmo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mezmo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mezmo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mezmo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mezmo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/microsoft-clarity-automation/SKILL.md",
    "content": "---\nname: Microsoft Clarity Automation\ndescription: \"Automate user behavior analytics with Microsoft Clarity -- export heatmap data, session metrics, and engagement analytics segmented by browser, device, country, source, and more through the Composio Microsoft Clarity integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Microsoft Clarity Automation\n\nExport **Microsoft Clarity** user behavior analytics directly from Claude Code. Pull heatmap data, session metrics, and engagement insights segmented by multiple dimensions without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/microsoft_clarity](https://composio.dev/toolkits/microsoft_clarity)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Microsoft Clarity account when prompted. The agent will provide an authentication link.\n3. Ensure your Clarity project has sufficient data collection enabled for the dimensions you want to analyze.\n\n---\n\n## Core Workflows\n\n### 1. Export Recent Analytics Data\n\nExport Clarity analytics data for the last 1-3 days, segmented by up to three dimensions simultaneously.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nKey parameters:\n- `numOfDays` (required) -- number of days to export: `1` (last 24h), `2` (last 48h), or `3` (last 72h)\n- `dimension1` -- first breakdown dimension\n- `dimension2` -- second breakdown dimension (optional)\n- `dimension3` -- third breakdown dimension (optional)\n\nAvailable dimensions:\n- `Browser` -- Chrome, Firefox, Safari, Edge, etc.\n- `Device` -- Desktop, Mobile, Tablet\n- `Country/Region` -- geographic location of users\n- `OS` -- Windows, macOS, iOS, Android, etc.\n- `Source` -- traffic source (e.g., google, direct, referral)\n- `Medium` -- traffic medium (organic, cpc, referral, etc.)\n- `Campaign` -- marketing campaign name\n- `Channel` -- traffic channel grouping\n- `URL` -- specific page URLs\n\nExample prompt: *\"Export Clarity data for the last 24 hours broken down by Device and Country/Region\"*\n\n---\n\n### 2. Device Performance Analysis\n\nAnalyze how user behavior differs across device types to optimize responsive design.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nConfiguration: `numOfDays: 3`, `dimension1: \"Device\"`, `dimension2: \"Browser\"`\n\nExample prompt: *\"Show me Clarity metrics for the last 3 days by Device and Browser\"*\n\n---\n\n### 3. Traffic Source Breakdown\n\nUnderstand which traffic sources drive the most engaged users.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nConfiguration: `numOfDays: 2`, `dimension1: \"Source\"`, `dimension2: \"Medium\"`\n\nExample prompt: *\"Export Clarity data for the last 48 hours broken down by Source and Medium\"*\n\n---\n\n### 4. Geographic User Behavior\n\nAnalyze user engagement patterns across different countries and regions.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nConfiguration: `numOfDays: 3`, `dimension1: \"Country/Region\"`, `dimension2: \"Device\"`\n\nExample prompt: *\"Get Clarity data for the last 72 hours segmented by Country/Region and Device type\"*\n\n---\n\n### 5. Page-Level Performance\n\nExamine which specific URLs have the highest or lowest engagement metrics.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nConfiguration: `numOfDays: 1`, `dimension1: \"URL\"`, `dimension2: \"Device\"`\n\nExample prompt: *\"Export yesterday's Clarity data broken down by URL and Device\"*\n\n---\n\n### 6. Campaign Attribution Analysis\n\nEvaluate marketing campaign effectiveness through user behavior metrics.\n\n**Tool:** `MICROSOFT_CLARITY_DATA_EXPORT`\n\nConfiguration: `numOfDays: 3`, `dimension1: \"Campaign\"`, `dimension2: \"Channel\"`, `dimension3: \"Device\"`\n\nExample prompt: *\"Show Clarity engagement data for the last 3 days by Campaign, Channel, and Device\"*\n\n---\n\n## Known Pitfalls\n\n- **Limited time window:** Data export is limited to the last 1, 2, or 3 days only. The `numOfDays` parameter only accepts values of 1, 2, or 3. For longer historical analysis, you need to run exports periodically and aggregate them externally.\n- **Dimension name exact match:** Dimension values must match exactly as listed (e.g., `Country/Region` not `country` or `region`). Case and slashes matter.\n- **Maximum three dimensions:** You can segment by up to three dimensions per export. For more complex analysis, run multiple exports with different dimension combinations.\n- **Data availability lag:** Clarity data may have a short processing delay. Very recent sessions (last few minutes) may not appear in exports.\n- **Single tool limitation:** The Clarity integration currently offers only the data export tool. For heatmap visualizations and session recordings, use the Clarity web dashboard directly.\n- **Response size:** Exports with high-cardinality dimensions like `URL` combined with other dimensions can produce large response payloads. Consider narrowing your time window or using fewer dimensions.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `MICROSOFT_CLARITY_DATA_EXPORT` | Export analytics data with up to 3 dimensional breakdowns |\n\n**Available Dimensions:**\n\n| Dimension | Description |\n|---|---|\n| `Browser` | Web browser (Chrome, Firefox, Safari, etc.) |\n| `Device` | Device type (Desktop, Mobile, Tablet) |\n| `Country/Region` | Geographic location |\n| `OS` | Operating system |\n| `Source` | Traffic source |\n| `Medium` | Traffic medium |\n| `Campaign` | Marketing campaign |\n| `Channel` | Traffic channel grouping |\n| `URL` | Specific page URL |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/microsoft-tenant-automation/SKILL.md",
    "content": "---\nname: microsoft-tenant-automation\ndescription: \"Automate Microsoft Tenant tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Microsoft Tenant Automation via Rube MCP\n\nAutomate Microsoft Tenant operations through Composio's Microsoft Tenant toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/microsoft_tenant](https://composio.dev/toolkits/microsoft_tenant)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Microsoft Tenant connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_tenant`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_tenant`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Microsoft Tenant operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Microsoft Tenant task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"microsoft_tenant\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Microsoft Tenant-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_tenant` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/microsoft_clarity-automation/SKILL.md",
    "content": "---\nname: microsoft_clarity-automation\ndescription: \"Automate Microsoft Clarity tasks via Rube MCP (Composio): session recordings, heatmaps, and user behavior analytics. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Microsoft Clarity Automation via Rube MCP\n\nAutomate Microsoft Clarity operations through Composio's Microsoft Clarity toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/microsoft_clarity](https://composio.dev/toolkits/microsoft_clarity)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Microsoft Clarity connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_clarity`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_clarity`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"session recordings, heatmaps, and user behavior analytics\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Microsoft Clarity\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Microsoft Clarity Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Microsoft Clarity tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Microsoft Clarity Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Microsoft Clarity operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Microsoft Clarity connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Microsoft Clarity-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `microsoft_clarity` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/microsoft_clarity](https://composio.dev/toolkits/microsoft_clarity)\n"
  },
  {
    "path": "composio-skills/minerstat-automation/SKILL.md",
    "content": "---\nname: minerstat-automation\ndescription: \"Automate Minerstat tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Minerstat Automation via Rube MCP\n\nAutomate Minerstat operations through Composio's Minerstat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/minerstat](https://composio.dev/toolkits/minerstat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Minerstat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `minerstat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `minerstat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Minerstat operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Minerstat task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"minerstat\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Minerstat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `minerstat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/missive-automation/SKILL.md",
    "content": "---\nname: missive-automation\ndescription: \"Automate Missive tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Missive Automation via Rube MCP\n\nAutomate Missive operations through Composio's Missive toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/missive](https://composio.dev/toolkits/missive)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Missive connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `missive`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `missive`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Missive operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Missive task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"missive\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Missive-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `missive` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mistral-ai-automation/SKILL.md",
    "content": "---\nname: Mistral AI Automation\ndescription: \"Automate Mistral AI operations -- manage files and libraries, upload documents for fine-tuning, batch processing, and OCR, track fine-tuning jobs, and build RAG pipelines via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Mistral AI Automation\n\nAutomate your Mistral AI workflows -- upload files for fine-tuning, batch processing, and OCR, manage document libraries for RAG-enabled agents, list and retrieve files, track fine-tuning jobs, and integrate Mistral AI into cross-app data pipelines.\n\n**Toolkit docs:** [composio.dev/toolkits/mistral_ai](https://composio.dev/toolkits/mistral_ai)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Mistral AI account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. Upload Files to Mistral AI\n\nUse `MISTRAL_AI_UPLOAD_FILE` to upload files for fine-tuning, batch processing, or OCR.\n\n```\nTool: MISTRAL_AI_UPLOAD_FILE\nInputs:\n  - file: object (required)\n    - name: string -- destination filename (e.g., \"training_data.jsonl\")\n    - mimetype: string -- MIME type (e.g., \"application/pdf\", \"application/jsonl\")\n    - s3key: string -- S3 key of a previously downloaded/stored file\n  - purpose: \"fine-tune\" | \"batch\" | \"ocr\" (default \"fine-tune\")\n```\n\n**Limits:** Maximum file size is 512 MB. For fine-tuning, only `.jsonl` files are supported.\n\n### 2. List and Retrieve Files\n\nUse `MISTRAL_AI_LIST_FILES` to browse uploaded files with pagination, and `MISTRAL_AI_RETRIEVE_FILE` to get metadata for a specific file.\n\n```\nTool: MISTRAL_AI_LIST_FILES\nInputs:\n  - limit: integer (optional, min 1)\n  - after: string (file ID cursor for next page)\n  - order: \"asc\" | \"desc\" (default \"desc\")\n\nTool: MISTRAL_AI_RETRIEVE_FILE\nInputs:\n  - file_id: string (required) -- UUID obtained from List Files\n```\n\n### 3. Create Document Libraries\n\nUse `MISTRAL_AI_CREATE_LIBRARY` to group documents into libraries for use with RAG-enabled Mistral AI agents.\n\n```\nTool: MISTRAL_AI_CREATE_LIBRARY\nInputs:\n  - name: string (required) -- e.g., \"Project Documents\"\n  - description: string (optional)\n```\n\n### 4. Upload Documents to a Library\n\nUse `MISTRAL_AI_UPLOAD_LIBRARY_DOCUMENT` to add documents to a library for RAG retrieval by Mistral AI agents.\n\n```\nTool: MISTRAL_AI_UPLOAD_LIBRARY_DOCUMENT\n  - Requires library_id and file details\n  - Call RUBE_GET_TOOL_SCHEMAS for full input schema before use\n```\n\n### 5. List Libraries and Download Files\n\nUse `MISTRAL_AI_LIST_LIBRARIES` to discover available document libraries, and `MISTRAL_AI_DOWNLOAD_FILE` to retrieve file content.\n\n```\nTool: MISTRAL_AI_LIST_LIBRARIES\n  - Lists all document libraries with metadata (id, name, document counts)\n  - Call RUBE_GET_TOOL_SCHEMAS for full input schema\n\nTool: MISTRAL_AI_DOWNLOAD_FILE\n  - Downloads raw binary content of a previously uploaded file\n  - Call RUBE_GET_TOOL_SCHEMAS for full input schema\n```\n\n### 6. Track Fine-Tuning Jobs\n\nUse `MISTRAL_AI_GET_FINE_TUNING_JOBS` to list and filter fine-tuning jobs by model, status, and creation time.\n\n```\nTool: MISTRAL_AI_GET_FINE_TUNING_JOBS\n  - Supports filtering by model, status, creation time, and W&B integration\n  - Call RUBE_GET_TOOL_SCHEMAS for full input schema\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Fine-tune file format | Only `.jsonl` files are supported for fine-tuning uploads. Other formats will be rejected. |\n| File size limit | Maximum upload size is 512 MB per file. |\n| File object structure | `MISTRAL_AI_UPLOAD_FILE` requires an `s3key` referencing a previously stored file, not raw binary content. Use a download action first to stage files in S3. |\n| Pagination cursors | `MISTRAL_AI_LIST_FILES` uses cursor-based pagination via the `after` parameter (file ID). Continue fetching until no more results are returned. |\n| Library document processing | Uploaded library documents are processed asynchronously. They may not be immediately available for RAG queries after upload. |\n| Schema references | Several tools (`MISTRAL_AI_UPLOAD_LIBRARY_DOCUMENT`, `MISTRAL_AI_LIST_LIBRARIES`, `MISTRAL_AI_GET_FINE_TUNING_JOBS`, `MISTRAL_AI_DOWNLOAD_FILE`) require calling `RUBE_GET_TOOL_SCHEMAS` to load full input schemas before execution. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `MISTRAL_AI_UPLOAD_FILE` | Upload files for fine-tuning, batch processing, or OCR |\n| `MISTRAL_AI_LIST_FILES` | List uploaded files with pagination |\n| `MISTRAL_AI_RETRIEVE_FILE` | Get metadata for a specific file by ID |\n| `MISTRAL_AI_DOWNLOAD_FILE` | Download content of an uploaded file |\n| `MISTRAL_AI_CREATE_LIBRARY` | Create a document library for RAG |\n| `MISTRAL_AI_LIST_LIBRARIES` | List all document libraries with metadata |\n| `MISTRAL_AI_UPLOAD_LIBRARY_DOCUMENT` | Add a document to a library for RAG |\n| `MISTRAL_AI_GET_FINE_TUNING_JOBS` | List and filter fine-tuning jobs |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mistral_ai-automation/SKILL.md",
    "content": "---\nname: mistral_ai-automation\ndescription: \"Automate Mistral AI tasks via Rube MCP (Composio): completions, embeddings, fine-tuning, and model management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mistral AI Automation via Rube MCP\n\nAutomate Mistral AI operations through Composio's Mistral AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mistral_ai](https://composio.dev/toolkits/mistral_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mistral AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mistral_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mistral_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"completions, embeddings, fine-tuning, and model management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Mistral AI\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Mistral AI Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Mistral AI tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Mistral AI Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Mistral AI operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Mistral AI connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mistral AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mistral_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/mistral_ai](https://composio.dev/toolkits/mistral_ai)\n"
  },
  {
    "path": "composio-skills/mocean-automation/SKILL.md",
    "content": "---\nname: mocean-automation\ndescription: \"Automate Mocean tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mocean Automation via Rube MCP\n\nAutomate Mocean operations through Composio's Mocean toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mocean](https://composio.dev/toolkits/mocean)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mocean connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mocean`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mocean`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mocean operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mocean task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mocean\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mocean-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mocean` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moco-automation/SKILL.md",
    "content": "---\nname: moco-automation\ndescription: \"Automate Moco tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moco Automation via Rube MCP\n\nAutomate Moco operations through Composio's Moco toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moco](https://composio.dev/toolkits/moco)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moco connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moco`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moco`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moco operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moco task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moco\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moco-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moco` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/modelry-automation/SKILL.md",
    "content": "---\nname: modelry-automation\ndescription: \"Automate Modelry tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Modelry Automation via Rube MCP\n\nAutomate Modelry operations through Composio's Modelry toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/modelry](https://composio.dev/toolkits/modelry)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Modelry connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `modelry`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `modelry`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Modelry operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Modelry task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"modelry\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Modelry-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `modelry` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moneybird-automation/SKILL.md",
    "content": "---\nname: moneybird-automation\ndescription: \"Automate Moneybird tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moneybird Automation via Rube MCP\n\nAutomate Moneybird operations through Composio's Moneybird toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moneybird](https://composio.dev/toolkits/moneybird)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moneybird connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moneybird`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moneybird`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moneybird operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moneybird task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moneybird\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moneybird-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moneybird` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moonclerk-automation/SKILL.md",
    "content": "---\nname: moonclerk-automation\ndescription: \"Automate Moonclerk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moonclerk Automation via Rube MCP\n\nAutomate Moonclerk operations through Composio's Moonclerk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moonclerk](https://composio.dev/toolkits/moonclerk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moonclerk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moonclerk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moonclerk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moonclerk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moonclerk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moonclerk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moonclerk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moonclerk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moosend-automation/SKILL.md",
    "content": "---\nname: moosend-automation\ndescription: \"Automate Moosend tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moosend Automation via Rube MCP\n\nAutomate Moosend operations through Composio's Moosend toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moosend](https://composio.dev/toolkits/moosend)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moosend connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moosend`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moosend`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moosend operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moosend task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moosend\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moosend-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moosend` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mopinion-automation/SKILL.md",
    "content": "---\nname: mopinion-automation\ndescription: \"Automate Mopinion tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mopinion Automation via Rube MCP\n\nAutomate Mopinion operations through Composio's Mopinion toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mopinion](https://composio.dev/toolkits/mopinion)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mopinion connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mopinion`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mopinion`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mopinion operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mopinion task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mopinion\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mopinion-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mopinion` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/more-trees-automation/SKILL.md",
    "content": "---\nname: more-trees-automation\ndescription: \"Automate More Trees tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# More Trees Automation via Rube MCP\n\nAutomate More Trees operations through Composio's More Trees toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/more_trees](https://composio.dev/toolkits/more_trees)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active More Trees connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `more_trees`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `more_trees`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"More Trees operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific More Trees task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"more_trees\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with More Trees-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `more_trees` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moxie-automation/SKILL.md",
    "content": "---\nname: moxie-automation\ndescription: \"Automate Moxie tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moxie Automation via Rube MCP\n\nAutomate Moxie operations through Composio's Moxie toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moxie](https://composio.dev/toolkits/moxie)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moxie connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moxie`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moxie`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moxie operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moxie task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moxie\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moxie-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moxie` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/moz-automation/SKILL.md",
    "content": "---\nname: moz-automation\ndescription: \"Automate Moz tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Moz Automation via Rube MCP\n\nAutomate Moz operations through Composio's Moz toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/moz](https://composio.dev/toolkits/moz)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Moz connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `moz`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `moz`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Moz operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Moz task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"moz\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Moz-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `moz` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/msg91-automation/SKILL.md",
    "content": "---\nname: msg91-automation\ndescription: \"Automate Msg91 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Msg91 Automation via Rube MCP\n\nAutomate Msg91 operations through Composio's Msg91 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/msg91](https://composio.dev/toolkits/msg91)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Msg91 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `msg91`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `msg91`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Msg91 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Msg91 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"msg91\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Msg91-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `msg91` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mural-automation/SKILL.md",
    "content": "---\nname: mural-automation\ndescription: \"Automate Mural tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mural Automation via Rube MCP\n\nAutomate Mural operations through Composio's Mural toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mural](https://composio.dev/toolkits/mural)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mural connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mural`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mural`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mural operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mural task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mural\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mural-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mural` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mx-technologies-automation/SKILL.md",
    "content": "---\nname: mx-technologies-automation\ndescription: \"Automate MX Technologies tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# MX Technologies Automation via Rube MCP\n\nAutomate MX Technologies operations through Composio's MX Technologies toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mx_technologies](https://composio.dev/toolkits/mx_technologies)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active MX Technologies connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_technologies`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_technologies`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"MX Technologies operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific MX Technologies task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mx_technologies\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with MX Technologies-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_technologies` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/mx-toolbox-automation/SKILL.md",
    "content": "---\nname: mx-toolbox-automation\ndescription: \"Automate Mx Toolbox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Mx Toolbox Automation via Rube MCP\n\nAutomate Mx Toolbox operations through Composio's Mx Toolbox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/mx_toolbox](https://composio.dev/toolkits/mx_toolbox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Mx Toolbox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_toolbox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_toolbox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Mx Toolbox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Mx Toolbox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"mx_toolbox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Mx Toolbox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `mx_toolbox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nango-automation/SKILL.md",
    "content": "---\nname: nango-automation\ndescription: \"Automate Nango tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nango Automation via Rube MCP\n\nAutomate Nango operations through Composio's Nango toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nango](https://composio.dev/toolkits/nango)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nango connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nango`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nango`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nango operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nango task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nango\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nango-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nango` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nano-nets-automation/SKILL.md",
    "content": "---\nname: nano-nets-automation\ndescription: \"Automate Nano Nets tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nano Nets Automation via Rube MCP\n\nAutomate Nano Nets operations through Composio's Nano Nets toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nano_nets](https://composio.dev/toolkits/nano_nets)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nano Nets connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nano_nets`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nano_nets`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nano Nets operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nano Nets task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nano_nets\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nano Nets-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nano_nets` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nasa-automation/SKILL.md",
    "content": "---\nname: nasa-automation\ndescription: \"Automate Nasa tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nasa Automation via Rube MCP\n\nAutomate Nasa operations through Composio's Nasa toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nasa](https://composio.dev/toolkits/nasa)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nasa connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nasa`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nasa`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nasa operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nasa task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nasa\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nasa-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nasa` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nasdaq-automation/SKILL.md",
    "content": "---\nname: nasdaq-automation\ndescription: \"Automate Nasdaq tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nasdaq Automation via Rube MCP\n\nAutomate Nasdaq operations through Composio's Nasdaq toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nasdaq](https://composio.dev/toolkits/nasdaq)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nasdaq connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nasdaq`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nasdaq`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nasdaq operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nasdaq task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nasdaq\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nasdaq-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nasdaq` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ncscale-automation/SKILL.md",
    "content": "---\nname: ncscale-automation\ndescription: \"Automate Ncscale tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ncscale Automation via Rube MCP\n\nAutomate Ncscale operations through Composio's Ncscale toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ncscale](https://composio.dev/toolkits/ncscale)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ncscale connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ncscale`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ncscale`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ncscale operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ncscale task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ncscale\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ncscale-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ncscale` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/needle-automation/SKILL.md",
    "content": "---\nname: needle-automation\ndescription: \"Automate Needle tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Needle Automation via Rube MCP\n\nAutomate Needle operations through Composio's Needle toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/needle](https://composio.dev/toolkits/needle)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Needle connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `needle`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `needle`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Needle operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Needle task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"needle\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Needle-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `needle` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/neon-automation/SKILL.md",
    "content": "---\nname: Neon Automation\ndescription: \"Automate Neon serverless Postgres operations -- manage projects, branches, databases, roles, and connection URIs via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Neon Automation\n\nAutomate your Neon serverless Postgres workflows -- list projects and branches, inspect databases, retrieve connection URIs, manage roles, and integrate Neon database operations into cross-app pipelines.\n\n**Toolkit docs:** [composio.dev/toolkits/neon](https://composio.dev/toolkits/neon)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Neon account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List Projects\n\nUse `NEON_RETRIEVE_PROJECTS_LIST` to discover all projects associated with the authenticated user.\n\n```\nTool: NEON_RETRIEVE_PROJECTS_LIST\nInputs:\n  - org_id: string (REQUIRED when using a personal API key)\n  - limit: integer (1-400, default 10)\n  - cursor: string (pagination cursor from previous response)\n  - search: string (search by project name or ID, supports partial match)\n  - timeout: integer (milliseconds; returns partial results on timeout)\n```\n\n**Important:** When using a personal API key, `org_id` is required. Retrieve it first via `NEON_GET_USER_ORGANIZATIONS`.\n\n### 2. Get Project Details\n\nUse `NEON_ACCESS_PROJECT_DETAILS_BY_ID` to inspect project configuration, owner info, and consumption metrics.\n\n```\nTool: NEON_ACCESS_PROJECT_DETAILS_BY_ID\nInputs:\n  - project_id: string (required) -- format: \"adjective-noun-number\", e.g., \"dry-smoke-26258271\"\n```\n\n### 3. List Branches for a Project\n\nUse `NEON_GET_BRANCHES_FOR_PROJECT` to enumerate branches (development stages) within a project.\n\n```\nTool: NEON_GET_BRANCHES_FOR_PROJECT\nInputs:\n  - project_id: string (required)\n  - search: string (optional, search by branch name or ID)\n```\n\n### 4. List Databases on a Branch\n\nUse `NEON_FETCH_DATABASE_FOR_BRANCH` to inventory databases within a specific project and branch.\n\n```\nTool: NEON_FETCH_DATABASE_FOR_BRANCH\nInputs:\n  - project_id: string (required)\n  - branch_id: string (required)\n```\n\n### 5. Get Connection URI\n\nUse `NEON_GET_PROJECT_CONNECTION_URI` to obtain a Postgres connection string for a project/branch/database.\n\n```\nTool: NEON_GET_PROJECT_CONNECTION_URI\nInputs:\n  - project_id: string (required)\n  - database_name: string (required) -- e.g., \"neondb\"\n  - role_name: string (required) -- e.g., \"neondb_owner\"\n  - branch_id: string (optional, defaults to project default branch)\n  - endpoint_id: string (optional, defaults to read-write endpoint)\n  - pooled: boolean (optional, adds -pooler for connection pooling)\n```\n\n**Security:** The returned URI includes credentials. Treat it as a secret -- do not log or share it.\n\n### 6. Inspect Database Details and Roles\n\nUse `NEON_RETRIEVE_BRANCH_DATABASE_DETAILS` to verify a database before connecting, and `NEON_GET_BRANCH_ROLES_FOR_PROJECT` to list available roles.\n\n```\nTool: NEON_RETRIEVE_BRANCH_DATABASE_DETAILS\nInputs:\n  - project_id: string (required)\n  - branch_id: string (required)\n  - database_name: string (required)\n\nTool: NEON_GET_BRANCH_ROLES_FOR_PROJECT\nInputs:\n  - project_id: string (required)\n  - branch_id: string (required)\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| org_id required | `NEON_RETRIEVE_PROJECTS_LIST` returns HTTP 400 \"org_id is required\" when using a personal API key. Call `NEON_GET_USER_ORGANIZATIONS` first. |\n| Incomplete pagination | Project lists may be incomplete without pagination. Iterate using `cursor` until it is empty. |\n| Rate limiting | `NEON_RETRIEVE_PROJECTS_LIST` returns HTTP 429 on bursty listing. Avoid redundant calls and back off before retrying. |\n| Invalid role/database pairing | `NEON_GET_PROJECT_CONNECTION_URI` returns 401/403 when the database_name/role_name pairing is invalid. Use `NEON_GET_BRANCH_ROLES_FOR_PROJECT` to select an allowed role. |\n| Connection URI is a secret | The returned URI includes credentials. Never log, display, or share it in plain text. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `NEON_RETRIEVE_PROJECTS_LIST` | List all Neon projects with pagination and search |\n| `NEON_ACCESS_PROJECT_DETAILS_BY_ID` | Get project configuration and consumption metrics |\n| `NEON_GET_BRANCHES_FOR_PROJECT` | List branches within a project |\n| `NEON_FETCH_DATABASE_FOR_BRANCH` | List databases on a specific branch |\n| `NEON_GET_PROJECT_CONNECTION_URI` | Get a Postgres connection URI (with credentials) |\n| `NEON_RETRIEVE_BRANCH_DATABASE_DETAILS` | Inspect database metadata and settings |\n| `NEON_GET_USER_ORGANIZATIONS` | List organizations for the authenticated user |\n| `NEON_CREATE_API_KEY_FOR_ORGANIZATION` | Create a new API key for an organization |\n| `NEON_GET_BRANCH_ROLES_FOR_PROJECT` | List roles available on a branch |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/netsuite-automation/SKILL.md",
    "content": "---\nname: NetSuite Automation\ndescription: \"NetSuite Automation: manage customers, sales orders, invoices, inventory, and records via Oracle NetSuite ERP with SuiteQL queries\"\nrequires:\n  mcp: [rube]\n---\n\n# NetSuite Automation\n\nAutomate Oracle NetSuite ERP operations including creating customers and sales orders, running SuiteQL queries, upserting records by external ID, and inspecting record metadata for comprehensive business management.\n\n**Toolkit docs:** [composio.dev/toolkits/netsuite](https://composio.dev/toolkits/netsuite)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `netsuite` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. Create Sales Orders\n\nCreate customer orders with line items including item references, quantities, and pricing.\n\n**Tool:** `NETSUITE_CREATE_SALES_ORDER`\n\n**Key Parameters:**\n- `entity` (required) -- Customer reference: `{\"id\": \"<internal_id>\"}`\n- `item` (required) -- Container with `items` array, each containing:\n  - `item` (required) -- Item reference: `{\"id\": \"<internal_id>\"}`\n  - `quantity` (required) -- Units to order (non-negative)\n  - `rate` -- Unit price (optional if item has default pricing)\n  - `amount` -- Total line amount (alternative to rate)\n  - `taxcode` -- Tax code reference: `{\"id\": \"<internal_id>\"}` (required if SuiteTax enabled)\n  - `description` -- Line item notes\n- `tranDate` -- Transaction date in `YYYY-MM-DD` format\n- `memo` -- Header memo\n- `orderStatus` -- `\"A\"` (Pending Approval) or `\"B\"` (Pending Fulfillment)\n- `otherrefnum` -- External reference or PO number\n\n**Example:**\n```\nTool: NETSUITE_CREATE_SALES_ORDER\nArguments:\n  entity: {\"id\": \"1234\"}\n  item: {\n    \"items\": [\n      {\"item\": {\"id\": \"56\"}, \"quantity\": 10, \"rate\": 25.00},\n      {\"item\": {\"id\": \"78\"}, \"quantity\": 5, \"rate\": 50.00}\n    ]\n  }\n  tranDate: \"2026-02-11\"\n  memo: \"Q1 bulk order\"\n  orderStatus: \"B\"\n```\n\n---\n\n### 2. Run SuiteQL Queries\n\nExecute ad-hoc SQL queries against NetSuite data with server-side paging.\n\n**Tool:** `NETSUITE_RUN_SUITEQL_QUERY`\n\n**Key Parameters:**\n- `q` (required) -- SuiteQL SELECT statement\n- `limit` -- Rows per page (default varies)\n- `offset` -- Zero-based index of first row (must be a multiple of `limit`)\n\n**Examples:**\n```\nTool: NETSUITE_RUN_SUITEQL_QUERY\nArguments:\n  q: \"SELECT id, companyname, email FROM customer WHERE isinactive = 'F' ORDER BY companyname\"\n  limit: 100\n  offset: 0\n```\n\n```\nTool: NETSUITE_RUN_SUITEQL_QUERY\nArguments:\n  q: \"SELECT id, entitystatus, total FROM transaction WHERE type = 'SalesOrd' AND trandate >= '2026-01-01'\"\n  limit: 50\n```\n\n---\n\n### 3. Create and Manage Customers\n\nCreate new customer records with subsidiary assignment and contact details.\n\n**Tools:**\n- `NETSUITE_CREATE_CUSTOMER` -- Create a new customer\n- `NETSUITE_GET_CUSTOMER` -- Retrieve customer by internal ID\n- `NETSUITE_UPDATE_CUSTOMER` -- Update existing customer (PATCH semantics)\n\n**Key Parameters for `NETSUITE_CREATE_CUSTOMER`:**\n- `body` (required) -- JSON object with customer data. Required fields:\n  - `subsidiary` -- Object with `id` (subsidiary internal ID)\n  - Either `companyName` (for businesses) or `firstName` + `lastName` (for individuals)\n  - Optional: `email`, `phone`, `isPerson` (set to `\"T\"` for individuals), `comments`\n- `replace` -- Comma-separated sublist names to fully replace (e.g., `\"contacts,addressbook\"`)\n\n**Example:**\n```\nTool: NETSUITE_CREATE_CUSTOMER\nArguments:\n  body: {\n    \"companyName\": \"Acme Corp\",\n    \"subsidiary\": {\"id\": \"1\"},\n    \"email\": \"info@acme.com\",\n    \"phone\": \"555-0100\"\n  }\n```\n\n---\n\n### 4. Upsert Records by External ID\n\nCreate or update records idempotently using an external identifier. Essential for sync workflows.\n\n**Tool:** `NETSUITE_UPSERT_RECORD_BY_EXTERNAL_ID`\n\n**Key Parameters:**\n- `record_type` (required) -- Record type name, e.g., `\"customer\"`, `\"salesorder\"`, `\"customrecord_myrec\"`\n- `external_id` (required) -- External ID value (letters, numbers, underscore, hyphen only)\n- `body` (required) -- JSON object matching the record schema; include mandatory fields when creating\n\n**Example:**\n```\nTool: NETSUITE_UPSERT_RECORD_BY_EXTERNAL_ID\nArguments:\n  record_type: \"customer\"\n  external_id: \"CRM-CUST-42\"\n  body: {\n    \"companyName\": \"Acme Corp\",\n    \"subsidiary\": {\"id\": \"1\"},\n    \"email\": \"updated@acme.com\"\n  }\n```\n\n> **Warning:** Idempotency depends on consistent external ID usage. Mismatches silently create additional records instead of updating.\n\n---\n\n### 5. Inspect Record Metadata\n\nDiscover available fields, data types, constraints, and requirements before creating or updating records.\n\n**Tool:** `NETSUITE_GET_RECORD_METADATA`\n\n**Key Parameters:**\n- `record_type` (required) -- e.g., `\"customer\"`, `\"salesorder\"`, `\"invoice\"`, `\"vendor\"`, `\"employee\"`, `\"item\"`\n- `accept` -- `\"application/schema+json\"` (default, JSON Schema) or `\"application/swagger+json\"` (OpenAPI 3.0)\n\n**Example:**\n```\nTool: NETSUITE_GET_RECORD_METADATA\nArguments:\n  record_type: \"salesorder\"\n```\n\n---\n\n### 6. List and Filter Records\n\nRetrieve multiple records with optional filtering and pagination.\n\n**Tool:** `NETSUITE_LIST_RECORDS`\n\n**Key Parameters:**\n- `recordType` (required) -- e.g., `\"customer\"`, `\"salesorder\"`\n- `q` -- Filter expression using N/query operators, e.g., `\"email START_WITH \\\"barbara\\\"\"`\n- `limit` -- Max records per page (1--1000, default 1000)\n- `offset` -- Zero-based index (must be divisible by limit)\n\n**Supporting Tools:**\n- `NETSUITE_FILTER_RECORD_COLLECTION` -- Alternative filtering (secondary to SuiteQL)\n- `NETSUITE_GET_RECORD_SELECTED_FIELDS` -- Retrieve specific fields only (reduced payload)\n\n---\n\n## Recommended Execution Plan\n\n1. **Inspect the record schema** using `NETSUITE_GET_RECORD_METADATA` to discover required fields\n2. **Search for existing records** using `NETSUITE_RUN_SUITEQL_QUERY` to avoid duplicates\n3. **Look up customer** by email using SuiteQL; fetch details with `NETSUITE_GET_CUSTOMER` if found\n4. **Create customer if needed** using `NETSUITE_CREATE_CUSTOMER` (ensure `subsidiary` is set)\n5. **Validate item internal IDs** using `NETSUITE_LIST_RECORDS` or SuiteQL\n6. **Create the sales order** using `NETSUITE_CREATE_SALES_ORDER` with validated references\n7. **Optionally upsert by external ID** using `NETSUITE_UPSERT_RECORD_BY_EXTERNAL_ID` for sync workflows\n8. **Verify results** using `NETSUITE_GET_RECORD_SELECTED_FIELDS` to confirm pricing/totals\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Invalid item IDs** | `NETSUITE_CREATE_SALES_ORDER` throws USER_ERROR when item internal ID is invalid. Pre-validate via `NETSUITE_LIST_RECORDS` or `NETSUITE_RUN_SUITEQL_QUERY`. |\n| **Missing required fields** | `NETSUITE_CREATE_CUSTOMER` returns 400 when required fields (e.g., `subsidiary`) are missing. Always inspect with `NETSUITE_GET_RECORD_METADATA` first. |\n| **SuiteQL field names** | Query differences by account can cause empty results. Confirm field names via `NETSUITE_GET_RECORD_METADATA` when results look wrong. |\n| **Filter expression limits** | `NETSUITE_FILTER_RECORD_COLLECTION` may fail if filter syntax is unsupported. Treat as secondary to SuiteQL. |\n| **External ID idempotency** | `NETSUITE_UPSERT_RECORD_BY_EXTERNAL_ID` depends on consistent external IDs. Mismatches silently create duplicates instead of updating. |\n| **SuiteTax line items** | Accounts with SuiteTax enabled require `taxcode` on every line item. Omitting it causes creation failures. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `NETSUITE_CREATE_SALES_ORDER` | Create a new sales order with line items |\n| `NETSUITE_RUN_SUITEQL_QUERY` | Execute ad-hoc SuiteQL queries with paging |\n| `NETSUITE_CREATE_CUSTOMER` | Create a new customer record |\n| `NETSUITE_GET_CUSTOMER` | Retrieve a customer by internal ID |\n| `NETSUITE_UPDATE_CUSTOMER` | Update an existing customer (PATCH) |\n| `NETSUITE_UPSERT_RECORD_BY_EXTERNAL_ID` | Create or update a record by external ID |\n| `NETSUITE_GET_RECORD_METADATA` | Inspect record schema and field definitions |\n| `NETSUITE_LIST_RECORDS` | List records with filtering and pagination |\n| `NETSUITE_FILTER_RECORD_COLLECTION` | Alternative record filtering |\n| `NETSUITE_GET_RECORD_SELECTED_FIELDS` | Retrieve specific fields from a record |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/neuronwriter-automation/SKILL.md",
    "content": "---\nname: neuronwriter-automation\ndescription: \"Automate Neuronwriter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Neuronwriter Automation via Rube MCP\n\nAutomate Neuronwriter operations through Composio's Neuronwriter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/neuronwriter](https://composio.dev/toolkits/neuronwriter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Neuronwriter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `neuronwriter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `neuronwriter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Neuronwriter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Neuronwriter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"neuronwriter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Neuronwriter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `neuronwriter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/neutrino-automation/SKILL.md",
    "content": "---\nname: neutrino-automation\ndescription: \"Automate Neutrino tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Neutrino Automation via Rube MCP\n\nAutomate Neutrino operations through Composio's Neutrino toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/neutrino](https://composio.dev/toolkits/neutrino)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Neutrino connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `neutrino`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `neutrino`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Neutrino operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Neutrino task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"neutrino\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Neutrino-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `neutrino` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/neverbounce-automation/SKILL.md",
    "content": "---\nname: neverbounce-automation\ndescription: \"Automate Neverbounce tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Neverbounce Automation via Rube MCP\n\nAutomate Neverbounce operations through Composio's Neverbounce toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/neverbounce](https://composio.dev/toolkits/neverbounce)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Neverbounce connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `neverbounce`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `neverbounce`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Neverbounce operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Neverbounce task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"neverbounce\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Neverbounce-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `neverbounce` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/new-relic-automation/SKILL.md",
    "content": "---\nname: New Relic Automation\ndescription: \"Automate New Relic observability workflows -- manage alert policies, notification channels, alert conditions, and monitor applications and browser apps via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# New Relic Automation\n\nAutomate your New Relic observability workflows -- create and manage alert policies, configure notification channels (email, Slack, webhook, PagerDuty), monitor APM applications, inspect alert conditions, and integrate New Relic alerting into cross-app pipelines.\n\n**Toolkit docs:** [composio.dev/toolkits/new_relic](https://composio.dev/toolkits/new_relic)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your New Relic account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List Alert Policies\n\nUse `NEW_RELIC_GET_ALERT_POLICIES` to discover existing alert policies with optional filtering.\n\n```\nTool: NEW_RELIC_GET_ALERT_POLICIES\nInputs:\n  - name: string (optional, partial match supported)\n  - incident_preference: \"PER_POLICY\" | \"PER_CONDITION\" | \"PER_CONDITION_AND_TARGET\"\n  - page: integer (1-indexed pagination)\n```\n\n### 2. Create an Alert Policy\n\nUse `NEW_RELIC_CREATE_ALERT_POLICY` to set up a new policy container for alert conditions.\n\n```\nTool: NEW_RELIC_CREATE_ALERT_POLICY\nInputs:\n  - name: string (required) -- must be unique within the account\n  - incident_preference: \"PER_POLICY\" | \"PER_CONDITION\" | \"PER_CONDITION_AND_TARGET\" (default: PER_POLICY)\n```\n\n**Incident preferences explained:**\n- `PER_POLICY` -- one issue per policy (recommended for most use cases)\n- `PER_CONDITION` -- one issue per alert condition\n- `PER_CONDITION_AND_TARGET` -- one issue per condition and signal/target\n\n### 3. Create Alert Notification Channels\n\nUse `NEW_RELIC_CREATE_ALERT_CHANNEL` to register notification endpoints for alert delivery.\n\n```\nTool: NEW_RELIC_CREATE_ALERT_CHANNEL\nInputs:\n  - type: \"email\" | \"slack\" | \"webhook\" | \"pagerduty\" | \"opsgenie\" | \"victorops\" (required)\n  - name: string (required) -- human-readable channel name\n  - configuration: object (required) -- varies by type:\n    Email:     { recipients: \"devops@example.com,oncall@example.com\" }\n    Slack:     { url: \"<slack_webhook_url>\", channel: \"alerts\" }\n    Webhook:   { url: \"https://hooks.example.com/alerts\", auth_username, auth_password }\n    PagerDuty: { service_key: \"<integration_key>\" }\n    OpsGenie:  { api_key, recipients, tags, teams }\n    VictorOps: { key: \"<api_key>\", route_key: \"<routing_key>\" }\n```\n\n### 4. Get Alert Conditions for a Policy\n\nUse `NEW_RELIC_GET_ALERT_CONDITIONS` to inspect the conditions attached to a specific policy.\n\n```\nTool: NEW_RELIC_GET_ALERT_CONDITIONS\nInputs:\n  - policy_id: integer (required)\n```\n\n### 5. Monitor Applications\n\nUse `NEW_RELIC_GET_APPLICATIONS` and `NEW_RELIC_GET_BROWSER_APPLICATIONS` to list APM and browser-monitored apps.\n\n```\nTool: NEW_RELIC_GET_APPLICATIONS\nInputs:\n  - name: string (optional, case-insensitive partial match)\n  - host: string (optional, case-insensitive partial match)\n  - ids: string (optional, comma-separated list of app IDs)\n  - page: integer (1-indexed)\n\nTool: NEW_RELIC_GET_BROWSER_APPLICATIONS\nInputs:\n  - filter[name]: string (optional, case-insensitive partial match)\n  - page: integer (1-indexed)\n```\n\n### 6. Manage Channels and Policies\n\nUse `NEW_RELIC_UPDATE_ALERT_CHANNEL` to modify existing channels and `NEW_RELIC_DELETE_ALERT_POLICY` to remove policies.\n\n```\nTool: NEW_RELIC_UPDATE_ALERT_CHANNEL\nInputs:\n  - alert_channel_id: integer (required)\n  - name: string (optional)\n  - type: string (optional, only to change type)\n  - configuration: object (optional, fields vary by type)\n\nTool: NEW_RELIC_DELETE_ALERT_POLICY\nInputs:\n  - policy_id: string (required) -- ID of the policy to delete\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Unique policy names | `NEW_RELIC_CREATE_ALERT_POLICY` requires the name to be unique within the account. |\n| Channel config varies by type | The `configuration` object for `NEW_RELIC_CREATE_ALERT_CHANNEL` has different required fields per channel type (e.g., `recipients` for email, `service_key` for PagerDuty). |\n| Pagination required | All list endpoints return paginated results. Iterate pages until results are exhausted. |\n| Policy ID type mismatch | `NEW_RELIC_GET_ALERT_CONDITIONS` expects `policy_id` as an integer, while `NEW_RELIC_DELETE_ALERT_POLICY` expects it as a string. |\n| Channel-policy linking | After creating a channel, you must separately associate it with a policy for alerts to flow to that channel. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `NEW_RELIC_GET_ALERT_POLICIES` | List alert policies with optional filtering |\n| `NEW_RELIC_CREATE_ALERT_POLICY` | Create a new alert policy |\n| `NEW_RELIC_DELETE_ALERT_POLICY` | Delete an alert policy by ID |\n| `NEW_RELIC_CREATE_ALERT_CHANNEL` | Create a notification channel (email, Slack, webhook, etc.) |\n| `NEW_RELIC_GET_ALERT_CHANNELS` | List all configured alert channels |\n| `NEW_RELIC_UPDATE_ALERT_CHANNEL` | Update an existing alert channel |\n| `NEW_RELIC_GET_ALERT_CONDITIONS` | Get alert conditions for a policy |\n| `NEW_RELIC_GET_APPLICATIONS` | List APM applications |\n| `NEW_RELIC_GET_BROWSER_APPLICATIONS` | List browser-monitored applications |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/new_relic-automation/SKILL.md",
    "content": "---\nname: new_relic-automation\ndescription: \"Automate New Relic tasks via Rube MCP (Composio): APM, alerts, dashboards, NRQL queries, and infrastructure monitoring. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# New Relic Automation via Rube MCP\n\nAutomate New Relic operations through Composio's New Relic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/new_relic](https://composio.dev/toolkits/new_relic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active New Relic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `new_relic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `new_relic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"APM, alerts, dashboards, NRQL queries, and infrastructure monitoring\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for New Relic\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available New Relic Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available New Relic tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute New Relic Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple New Relic operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the New Relic connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with New Relic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `new_relic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/new_relic](https://composio.dev/toolkits/new_relic)\n"
  },
  {
    "path": "composio-skills/news-api-automation/SKILL.md",
    "content": "---\nname: news-api-automation\ndescription: \"Automate News API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# News API Automation via Rube MCP\n\nAutomate News API operations through Composio's News API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/news_api](https://composio.dev/toolkits/news_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active News API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `news_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `news_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"News API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific News API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"news_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with News API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `news_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nextdns-automation/SKILL.md",
    "content": "---\nname: nextdns-automation\ndescription: \"Automate Nextdns tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nextdns Automation via Rube MCP\n\nAutomate Nextdns operations through Composio's Nextdns toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nextdns](https://composio.dev/toolkits/nextdns)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nextdns connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nextdns`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nextdns`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nextdns operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nextdns task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nextdns\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nextdns-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nextdns` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ngrok-automation/SKILL.md",
    "content": "---\nname: ngrok-automation\ndescription: \"Automate Ngrok tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ngrok Automation via Rube MCP\n\nAutomate Ngrok operations through Composio's Ngrok toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ngrok](https://composio.dev/toolkits/ngrok)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ngrok connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ngrok`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ngrok`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ngrok operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ngrok task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ngrok\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ngrok-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ngrok` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ninox-automation/SKILL.md",
    "content": "---\nname: ninox-automation\ndescription: \"Automate Ninox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ninox Automation via Rube MCP\n\nAutomate Ninox operations through Composio's Ninox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ninox](https://composio.dev/toolkits/ninox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ninox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ninox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ninox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ninox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ninox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ninox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ninox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ninox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/nocrm-io-automation/SKILL.md",
    "content": "---\nname: nocrm-io-automation\ndescription: \"Automate Nocrm IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Nocrm IO Automation via Rube MCP\n\nAutomate Nocrm IO operations through Composio's Nocrm IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/nocrm_io](https://composio.dev/toolkits/nocrm_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Nocrm IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `nocrm_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `nocrm_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Nocrm IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Nocrm IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"nocrm_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Nocrm IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `nocrm_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/npm-automation/SKILL.md",
    "content": "---\nname: npm-automation\ndescription: \"Automate NPM tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# NPM Automation via Rube MCP\n\nAutomate NPM operations through Composio's NPM toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/npm](https://composio.dev/toolkits/npm)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active NPM connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `npm`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `npm`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"NPM operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific NPM task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"npm\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with NPM-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `npm` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ocr-web-service-automation/SKILL.md",
    "content": "---\nname: ocr-web-service-automation\ndescription: \"Automate OCR Web Service tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# OCR Web Service Automation via Rube MCP\n\nAutomate OCR Web Service operations through Composio's OCR Web Service toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ocr_web_service](https://composio.dev/toolkits/ocr_web_service)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active OCR Web Service connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ocr_web_service`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ocr_web_service`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"OCR Web Service operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific OCR Web Service task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ocr_web_service\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with OCR Web Service-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ocr_web_service` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ocrspace-automation/SKILL.md",
    "content": "---\nname: ocrspace-automation\ndescription: \"Automate Ocrspace tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ocrspace Automation via Rube MCP\n\nAutomate Ocrspace operations through Composio's Ocrspace toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ocrspace](https://composio.dev/toolkits/ocrspace)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ocrspace connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ocrspace`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ocrspace`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ocrspace operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ocrspace task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ocrspace\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ocrspace-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ocrspace` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/omnisend-automation/SKILL.md",
    "content": "---\nname: Omnisend Automation\ndescription: \"Automate ecommerce marketing workflows including contact management, bulk operations, and subscriber segmentation through Omnisend via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Omnisend Automation\n\nAutomate ecommerce marketing operations -- create and update contacts, manage subscriber lists with cursor pagination, run bulk batch operations, and segment audiences -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/omnisend](https://composio.dev/toolkits/omnisend)\n\n---\n\n## Setup\n\n1. Connect your Omnisend account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `OMNISEND_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. Create or Update a Contact\nUpsert a contact by email identifier with subscription status, profile fields, and optional welcome message.\n\n**Tool:** `OMNISEND_CREATE_OR_UPDATE_CONTACT`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `identifiers` | array | Yes | At least one identifier object with `id` (email), `type` (`email`), optional `channels.email.status` (`subscribed`, `nonSubscribed`, `unsubscribed`), and `sendWelcomeMessage` (boolean) |\n| `firstName` | string | No | Contact's first name |\n| `lastName` | string | No | Contact's last name |\n| `gender` | string | No | `m` or `f` |\n| `birthdate` | string | No | Format: `YYYY-MM-DD` |\n| `country` | string | No | Full country name |\n| `countryCode` | string | No | ISO 3166-1 alpha-2 code (e.g., `US`) |\n| `city` | string | No | City name |\n| `address` | string | No | Street address |\n| `postalCode` | string | No | ZIP/postal code |\n\n---\n\n### 2. List Contacts with Pagination\nRetrieve contacts in batches with optional filters for email, phone, status, segment, or tag.\n\n**Tool:** `OMNISEND_LIST_CONTACTS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `limit` | integer | No | Results per page (default: 100, max: 250) |\n| `after` | string | No | Cursor for next page (base64-encoded ContactID) |\n| `before` | string | No | Cursor for previous page |\n| `email` | string | No | Filter by exact email address |\n| `phone` | string | No | Filter by full phone number with country code |\n| `status` | string | No | Filter by: `subscribed`, `nonSubscribed`, `unsubscribed` |\n| `segmentID` | integer | No | Filter by segment ID |\n| `tag` | string | No | Filter by tag (e.g., `VIP`) |\n\n---\n\n### 3. Get Contact Details\nRetrieve the full profile for a single contact when you already have their contact ID.\n\n**Tool:** `OMNISEND_GET_CONTACT`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `contactId` | string | Yes | Unique contact identifier (e.g., `60e7412b1234567890abcdef`) |\n\n---\n\n### 4. Update an Existing Contact\nPatch specific fields on a contact by ID without overwriting the entire record.\n\n**Tool:** `OMNISEND_UPDATE_CONTACT`\n\nRequires the `contactId` and the fields to update. Retrieve the contact ID first via `OMNISEND_LIST_CONTACTS` or `OMNISEND_GET_CONTACT`.\n\n---\n\n### 5. Bulk Batch Operations\nProcess many records asynchronously in a single call -- contacts, products, orders, events, or categories.\n\n**Tool:** `OMNISEND_CREATE_BATCH`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `method` | string | Yes | `POST` or `PUT` |\n| `endpoint` | string | Yes | Target: `contacts`, `orders`, `products`, `events`, `categories` |\n| `items` | array | Yes | Array of payload objects for each operation |\n| `eventID` | string | Conditional | Required when endpoint is `events` |\n\nUse batch operations to avoid rate limits when processing large data sets.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Identifier required** | `OMNISEND_CREATE_OR_UPDATE_CONTACT` requires at least one identifier in the `identifiers` array -- only `email` type is supported |\n| **Cursor-based pagination** | `OMNISEND_LIST_CONTACTS` uses base64-encoded `after`/`before` cursors, not page numbers -- follow cursors to avoid incomplete data |\n| **Contact ID resolution** | `OMNISEND_UPDATE_CONTACT` requires a `contactId` -- always resolve it first via list or get operations |\n| **Batch method constraints** | `OMNISEND_CREATE_BATCH` only accepts `POST` or `PUT` methods -- no `DELETE` or `PATCH` |\n| **Event ID dependency** | When batching events, the `eventID` parameter is mandatory -- omitting it causes the batch to fail |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `OMNISEND_CREATE_OR_UPDATE_CONTACT` | Create or upsert a contact by email |\n| `OMNISEND_LIST_CONTACTS` | List contacts with filtering and cursor pagination |\n| `OMNISEND_GET_CONTACT` | Get full profile for a single contact by ID |\n| `OMNISEND_UPDATE_CONTACT` | Patch specific fields on an existing contact |\n| `OMNISEND_CREATE_BATCH` | Bulk async operations for contacts, products, orders, events |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/oncehub-automation/SKILL.md",
    "content": "---\nname: oncehub-automation\ndescription: \"Automate Oncehub tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Oncehub Automation via Rube MCP\n\nAutomate Oncehub operations through Composio's Oncehub toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/oncehub](https://composio.dev/toolkits/oncehub)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Oncehub connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `oncehub`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `oncehub`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Oncehub operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Oncehub task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"oncehub\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Oncehub-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `oncehub` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/onedesk-automation/SKILL.md",
    "content": "---\nname: onedesk-automation\ndescription: \"Automate Onedesk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Onedesk Automation via Rube MCP\n\nAutomate Onedesk operations through Composio's Onedesk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/onedesk](https://composio.dev/toolkits/onedesk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Onedesk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `onedesk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `onedesk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Onedesk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Onedesk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"onedesk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Onedesk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `onedesk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/onepage-automation/SKILL.md",
    "content": "---\nname: onepage-automation\ndescription: \"Automate Onepage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Onepage Automation via Rube MCP\n\nAutomate Onepage operations through Composio's Onepage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/onepage](https://composio.dev/toolkits/onepage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Onepage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `onepage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `onepage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Onepage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Onepage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"onepage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Onepage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `onepage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/onesignal-rest-api-automation/SKILL.md",
    "content": "---\nname: onesignal-rest-api-automation\ndescription: \"Automate OneSignal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# OneSignal Automation via Rube MCP\n\nAutomate OneSignal operations through Composio's OneSignal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/onesignal_rest_api](https://composio.dev/toolkits/onesignal_rest_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active OneSignal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"OneSignal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific OneSignal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"onesignal_rest_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with OneSignal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/onesignal-user-auth-automation/SKILL.md",
    "content": "---\nname: onesignal-user-auth-automation\ndescription: \"Automate Onesignal User Auth tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Onesignal User Auth Automation via Rube MCP\n\nAutomate Onesignal User Auth operations through Composio's Onesignal User Auth toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/onesignal_user_auth](https://composio.dev/toolkits/onesignal_user_auth)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Onesignal User Auth connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_user_auth`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_user_auth`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Onesignal User Auth operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Onesignal User Auth task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"onesignal_user_auth\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Onesignal User Auth-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_user_auth` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/onesignal_rest_api-automation/SKILL.md",
    "content": "---\nname: onesignal_rest_api-automation\ndescription: \"Automate OneSignal tasks via Rube MCP (Composio): push notifications, segments, templates, and messaging. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# OneSignal Automation via Rube MCP\n\nAutomate OneSignal operations through Composio's OneSignal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/onesignal_rest_api](https://composio.dev/toolkits/onesignal_rest_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active OneSignal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"push notifications, segments, templates, and messaging\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for OneSignal\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available OneSignal Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available OneSignal tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute OneSignal Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple OneSignal operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the OneSignal connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with OneSignal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `onesignal_rest_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/onesignal_rest_api](https://composio.dev/toolkits/onesignal_rest_api)\n"
  },
  {
    "path": "composio-skills/open-sea-automation/SKILL.md",
    "content": "---\nname: open-sea-automation\ndescription: \"Automate Open Sea tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Open Sea Automation via Rube MCP\n\nAutomate Open Sea operations through Composio's Open Sea toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/open_sea](https://composio.dev/toolkits/open_sea)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Open Sea connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `open_sea`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `open_sea`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Open Sea operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Open Sea task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"open_sea\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Open Sea-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `open_sea` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/openai-automation/SKILL.md",
    "content": "---\nname: OpenAI Automation\ndescription: \"Automate OpenAI API operations -- generate responses with multimodal and structured output support, create embeddings, generate images, and list models via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# OpenAI Automation\n\nAutomate your OpenAI API workflows -- generate text with the Responses API (including multimodal image+text inputs and structured JSON outputs), create embeddings for search and clustering, generate images with DALL-E and GPT Image models, and list available models.\n\n**Toolkit docs:** [composio.dev/toolkits/openai](https://composio.dev/toolkits/openai)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your OpenAI account when prompted (API key authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. Generate a Response (Text, Multimodal, Structured)\n\nUse `OPENAI_CREATE_RESPONSE` for one-shot model responses including text, image analysis, OCR, and structured JSON outputs.\n\n```\nTool: OPENAI_CREATE_RESPONSE\nInputs:\n  - model: string (required) -- e.g., \"gpt-5\", \"gpt-4o\", \"o3-mini\"\n  - input: string | array (required)\n    Simple: \"Explain quantum computing\"\n    Multimodal: [\n      { role: \"user\", content: [\n        { type: \"input_text\", text: \"What is in this image?\" },\n        { type: \"input_image\", image_url: { url: \"https://...\" } }\n      ]}\n    ]\n  - temperature: number (0-2, optional -- not supported with reasoning models)\n  - max_output_tokens: integer (optional)\n  - reasoning: { effort: \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" }\n  - text: object (structured output config)\n    - format: { type: \"json_schema\", name: \"...\", schema: {...}, strict: true }\n  - tools: array (function, code_interpreter, file_search, web_search)\n  - tool_choice: \"auto\" | \"none\" | \"required\" | { type: \"function\", function: { name: \"...\" } }\n  - store: boolean (false to opt out of model distillation)\n  - stream: boolean\n```\n\n**Structured output example:** Set `text.format` to `{ type: \"json_schema\", name: \"person\", schema: { type: \"object\", properties: { name: { type: \"string\" }, age: { type: \"integer\" } }, required: [\"name\", \"age\"], additionalProperties: false }, strict: true }`.\n\n### 2. Create Embeddings\n\nUse `OPENAI_CREATE_EMBEDDINGS` for vector search, clustering, recommendations, and RAG pipelines.\n\n```\nTool: OPENAI_CREATE_EMBEDDINGS\nInputs:\n  - input: string | string[] | int[] | int[][] (required) -- max 8192 tokens, max 2048 items\n  - model: string (required) -- \"text-embedding-3-small\", \"text-embedding-3-large\", \"text-embedding-ada-002\"\n  - dimensions: integer (optional, only for text-embedding-3 and later)\n  - encoding_format: \"float\" | \"base64\" (default \"float\")\n  - user: string (optional, end-user ID for abuse monitoring)\n```\n\n### 3. Generate Images\n\nUse `OPENAI_CREATE_IMAGE` to create images from text prompts using GPT Image or DALL-E models.\n\n```\nTool: OPENAI_CREATE_IMAGE\nInputs:\n  - model: string (required) -- \"gpt-image-1\", \"gpt-image-1.5\", \"dall-e-3\", \"dall-e-2\"\n  - prompt: string (required) -- max 32000 chars (GPT Image), 4000 (DALL-E 3), 1000 (DALL-E 2)\n  - size: \"1024x1024\" | \"1536x1024\" | \"1024x1536\" | \"auto\" | \"256x256\" | \"512x512\" | \"1792x1024\" | \"1024x1792\"\n  - quality: \"standard\" | \"hd\" | \"auto\" | \"high\" | \"medium\" | \"low\"\n  - n: integer (1-10; DALL-E 3 supports n=1 only)\n  - background: \"transparent\" | \"opaque\" | \"auto\" (GPT Image models only)\n  - style: \"vivid\" | \"natural\" (DALL-E 3 only)\n  - user: string (optional)\n```\n\n### 4. List Available Models\n\nUse `OPENAI_LIST_MODELS` to discover which models are accessible with your API key.\n\n```\nTool: OPENAI_LIST_MODELS\nInputs: (none)\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| DALL-E deprecation | DALL-E 2 and DALL-E 3 are deprecated and will stop being supported on 05/12/2026. Prefer GPT Image models. |\n| DALL-E 3 single image only | `OPENAI_CREATE_IMAGE` with DALL-E 3 only supports `n=1`. Use GPT Image models or DALL-E 2 for multiple images. |\n| Token limits for embeddings | Input must not exceed 8192 tokens per item and 2048 items per batch for embedding models. |\n| Reasoning model restrictions | `temperature` and `top_p` are not supported with reasoning models (o3-mini, etc.). Use `reasoning.effort` instead. |\n| Structured output strict mode | When `strict: true` in json_schema format, ALL schema properties must be listed in the `required` array. |\n| Prompt length varies by model | Image prompt max lengths differ: 32000 (GPT Image), 4000 (DALL-E 3), 1000 (DALL-E 2). |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `OPENAI_CREATE_RESPONSE` | Generate text/multimodal responses with structured output support |\n| `OPENAI_CREATE_EMBEDDINGS` | Create text embeddings for search, clustering, and RAG |\n| `OPENAI_CREATE_IMAGE` | Generate images from text prompts |\n| `OPENAI_LIST_MODELS` | List all models available to your API key |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/opencage-automation/SKILL.md",
    "content": "---\nname: opencage-automation\ndescription: \"Automate Opencage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Opencage Automation via Rube MCP\n\nAutomate Opencage operations through Composio's Opencage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/opencage](https://composio.dev/toolkits/opencage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Opencage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `opencage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `opencage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Opencage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Opencage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"opencage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Opencage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `opencage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/opengraph-io-automation/SKILL.md",
    "content": "---\nname: opengraph-io-automation\ndescription: \"Automate Opengraph IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Opengraph IO Automation via Rube MCP\n\nAutomate Opengraph IO operations through Composio's Opengraph IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/opengraph_io](https://composio.dev/toolkits/opengraph_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Opengraph IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `opengraph_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `opengraph_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Opengraph IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Opengraph IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"opengraph_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Opengraph IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `opengraph_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/openperplex-automation/SKILL.md",
    "content": "---\nname: openperplex-automation\ndescription: \"Automate Openperplex tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Openperplex Automation via Rube MCP\n\nAutomate Openperplex operations through Composio's Openperplex toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/openperplex](https://composio.dev/toolkits/openperplex)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Openperplex connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `openperplex`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `openperplex`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Openperplex operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Openperplex task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"openperplex\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Openperplex-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `openperplex` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/openrouter-automation/SKILL.md",
    "content": "---\nname: openrouter-automation\ndescription: \"Automate Openrouter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Openrouter Automation via Rube MCP\n\nAutomate Openrouter operations through Composio's Openrouter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/openrouter](https://composio.dev/toolkits/openrouter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Openrouter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `openrouter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `openrouter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Openrouter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Openrouter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"openrouter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Openrouter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `openrouter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/openweather-api-automation/SKILL.md",
    "content": "---\nname: openweather-api-automation\ndescription: \"Automate Openweather API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Openweather API Automation via Rube MCP\n\nAutomate Openweather API operations through Composio's Openweather API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/openweather_api](https://composio.dev/toolkits/openweather_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Openweather API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `openweather_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `openweather_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Openweather API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Openweather API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"openweather_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Openweather API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `openweather_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/optimoroute-automation/SKILL.md",
    "content": "---\nname: optimoroute-automation\ndescription: \"Automate Optimoroute tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Optimoroute Automation via Rube MCP\n\nAutomate Optimoroute operations through Composio's Optimoroute toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/optimoroute](https://composio.dev/toolkits/optimoroute)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Optimoroute connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `optimoroute`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `optimoroute`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Optimoroute operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Optimoroute task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"optimoroute\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Optimoroute-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `optimoroute` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/owl-protocol-automation/SKILL.md",
    "content": "---\nname: owl-protocol-automation\ndescription: \"Automate Owl Protocol tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Owl Protocol Automation via Rube MCP\n\nAutomate Owl Protocol operations through Composio's Owl Protocol toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/owl_protocol](https://composio.dev/toolkits/owl_protocol)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Owl Protocol connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `owl_protocol`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `owl_protocol`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Owl Protocol operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Owl Protocol task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"owl_protocol\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Owl Protocol-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `owl_protocol` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/page-x-automation/SKILL.md",
    "content": "---\nname: page-x-automation\ndescription: \"Automate Page X tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Page X Automation via Rube MCP\n\nAutomate Page X operations through Composio's Page X toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/page_x](https://composio.dev/toolkits/page_x)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Page X connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `page_x`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `page_x`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Page X operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Page X task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"page_x\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Page X-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `page_x` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pandadoc-automation/SKILL.md",
    "content": "---\nname: PandaDoc Automation\ndescription: \"Automate document workflows with PandaDoc -- create documents from files, manage contacts, organize folders, set up webhooks, create templates, and track document status through the Composio PandaDoc integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# PandaDoc Automation\n\nManage **PandaDoc** document workflows directly from Claude Code. Create documents from uploaded files, manage recipients and contacts, organize with folders, set up event webhooks, create templates, and track document status without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/pandadoc](https://composio.dev/toolkits/pandadoc)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your PandaDoc account when prompted. The agent will provide an OAuth link to authenticate.\n3. Ensure your PandaDoc workspace has the appropriate plan for the features you need (e.g., e-signatures, templates, webhooks).\n\n---\n\n## Core Workflows\n\n### 1. Create a Document from File\n\nUpload a PDF, DOCX, or RTF file to create a new PandaDoc document with designated recipients for signing and tracking.\n\n**Tool:** `PANDADOC_CREATE_DOCUMENT_FROM_FILE`\n\nKey parameters:\n- `name` (required) -- document name\n- `recipients` (required) -- array of recipient objects, each with:\n  - `email` (required) -- recipient email\n  - `first_name`, `last_name` -- recipient name\n  - `role` -- `signer` (default), `approver`, or `cc` (must be unique per recipient)\n  - `signing_order` -- numeric order (if set for one, must be set for all)\n- `file` -- uploaded file object with `name`, `mimetype`, and `s3key`\n- `url` -- alternatively, a public HTTPS URL to the file\n- `parse_form_fields` (default false) -- parse PDF form fields\n- `tags` -- array of strings for categorization\n- `owner` -- document owner (email or membership_id)\n\nExample prompt: *\"Create a PandaDoc document from contract.pdf with john@example.com as signer and jane@example.com as approver\"*\n\n---\n\n### 2. Get Document Details\n\nFetch comprehensive metadata for a document including recipients, fields, tokens, pricing, tags, and content-block references.\n\n**Tool:** `PANDADOC_GET_DOCUMENT_DETAILS`\n\nKey parameters:\n- `id` (required) -- the unique document identifier (e.g., `BhVzRcxH9Z2LgfPPGXFUqa`)\n\nUse this to check document status, inspect recipient completion, review field values, or gather metadata for reporting.\n\nExample prompt: *\"Get the full details and status for PandaDoc document BhVzRcxH9Z2LgfPPGXFUqa\"*\n\n---\n\n### 3. Manage Contacts\n\nCreate new contacts or update existing ones in PandaDoc. Contacts are matched by email -- if a contact with the given email exists, it gets updated; otherwise, a new one is created.\n\n**Tool:** `PANDADOC_CREATE_OR_UPDATE_CONTACT`\n\nKey parameters:\n- `email` (required) -- contact email address\n- `first_name`, `last_name` -- contact name\n- `company` -- company name\n- `job_title` -- role/title\n- `phone` -- phone number\n- `street_address`, `city`, `state`, `postal_code`, `country` -- address fields\n\nExample prompt: *\"Create a PandaDoc contact for john.doe@example.com at Acme Corp as Software Engineer\"*\n\n---\n\n### 4. Organize with Folders\n\nCreate folders and move documents to organize your PandaDoc workspace.\n\n**Tools:** `PANDADOC_CREATE_FOLDER`, `PANDADOC_LIST_DOCUMENT_FOLDERS`, `PANDADOC_MOVE_DOCUMENT_TO_FOLDER`\n\nFor creating folders:\n- `name` (required) -- folder name\n- `parent_uuid` -- parent folder UUID for nested structures\n\nExample prompt: *\"Create a 'Q1 2026 Contracts' folder in PandaDoc and move document BhVzRcxH9Z to it\"*\n\n---\n\n### 5. Set Up Webhooks\n\nCreate webhook subscriptions to receive real-time notifications when document events occur.\n\n**Tool:** `PANDADOC_CREATE_WEBHOOK`\n\nKey parameters:\n- `name` (required) -- descriptive name for the webhook\n- `url` (required) -- endpoint URL for notifications\n- `triggers` (required) -- event types: `document_state_changed`, `recipient_completed`, `document_updated`, etc.\n- `active` (default true) -- enable/disable the webhook\n- `payload` -- additional data to include: `fields`, `products`, `metadata`, `tokens`, `pricing`\n\nExample prompt: *\"Set up a PandaDoc webhook to notify https://api.example.com/hooks when documents change state or recipients complete\"*\n\n---\n\n### 6. Create Templates\n\nCreate reusable templates from PDF files or from scratch with structured content blocks.\n\n**Tool:** `PANDADOC_CREATE_TEMPLATE`\n\nKey parameters:\n- `name` (required) -- template name\n- `file_path` -- path to PDF file for template creation\n- `content` -- structured content object with `title` and `blocks` array for building from scratch\n- `description` -- template description\n- `tags` -- categorization tags\n\nExample prompt: *\"Create a PandaDoc template called 'Standard NDA' from the nda-template.pdf file\"*\n\n---\n\n## Known Pitfalls\n\n- **Unique recipient roles:** PandaDoc API does not allow duplicate roles within a single document. Each recipient must have a unique `role` value (e.g., `signer`, `signer_2`, `approver`, `cc`).\n- **Signing order consistency:** If you specify `signing_order` for any recipient, you must specify it for ALL recipients in the document. Partial ordering will cause errors.\n- **File upload requirements:** Either `file` (with `s3key`) or `url` must be provided for document creation, not both. The URL must be publicly accessible HTTPS.\n- **Contact upsert behavior:** `PANDADOC_CREATE_OR_UPDATE_CONTACT` matches by email. If you need to update a contact's email itself, you must create a new contact and handle the old one separately.\n- **Document ID format:** Document IDs are alphanumeric strings (e.g., `BhVzRcxH9Z2LgfPPGXFUqa`). They are returned when documents are created and can be found via the PandaDoc dashboard.\n- **Webhook event naming:** Trigger event names must match exactly (e.g., `document_state_changed`, not `stateChanged` or `state_changed`). Check PandaDoc API docs for the complete list.\n- **Folder operations require UUIDs:** Moving documents requires both the document ID and the destination folder UUID. List folders first to get the correct UUID.\n- **Template content blocks:** When creating templates from scratch, the `blocks` array must contain valid content block objects per PandaDoc's schema. Check their API documentation for supported block types.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `PANDADOC_CREATE_DOCUMENT_FROM_FILE` | Create a document from PDF/DOCX/RTF with recipients |\n| `PANDADOC_GET_DOCUMENT_DETAILS` | Get full document metadata, status, and fields |\n| `PANDADOC_CREATE_OR_UPDATE_CONTACT` | Create or update a contact by email |\n| `PANDADOC_CREATE_FOLDER` | Create a folder for document organization |\n| `PANDADOC_LIST_DOCUMENT_FOLDERS` | List all document folders |\n| `PANDADOC_MOVE_DOCUMENT_TO_FOLDER` | Move a document to a specific folder |\n| `PANDADOC_CREATE_WEBHOOK` | Set up event notification webhooks |\n| `PANDADOC_CREATE_TEMPLATE` | Create a reusable document template |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/paradym-automation/SKILL.md",
    "content": "---\nname: paradym-automation\ndescription: \"Automate Paradym tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Paradym Automation via Rube MCP\n\nAutomate Paradym operations through Composio's Paradym toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/paradym](https://composio.dev/toolkits/paradym)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Paradym connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `paradym`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `paradym`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Paradym operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Paradym task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"paradym\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Paradym-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `paradym` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/parallel-automation/SKILL.md",
    "content": "---\nname: parallel-automation\ndescription: \"Automate Parallel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Parallel Automation via Rube MCP\n\nAutomate Parallel operations through Composio's Parallel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/parallel](https://composio.dev/toolkits/parallel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Parallel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `parallel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `parallel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Parallel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Parallel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"parallel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Parallel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `parallel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/parma-automation/SKILL.md",
    "content": "---\nname: parma-automation\ndescription: \"Automate Parma tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Parma Automation via Rube MCP\n\nAutomate Parma operations through Composio's Parma toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/parma](https://composio.dev/toolkits/parma)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Parma connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `parma`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `parma`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Parma operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Parma task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"parma\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Parma-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `parma` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/parsehub-automation/SKILL.md",
    "content": "---\nname: parsehub-automation\ndescription: \"Automate Parsehub tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Parsehub Automation via Rube MCP\n\nAutomate Parsehub operations through Composio's Parsehub toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/parsehub](https://composio.dev/toolkits/parsehub)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Parsehub connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `parsehub`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `parsehub`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Parsehub operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Parsehub task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"parsehub\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Parsehub-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `parsehub` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/parsera-automation/SKILL.md",
    "content": "---\nname: parsera-automation\ndescription: \"Automate Parsera tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Parsera Automation via Rube MCP\n\nAutomate Parsera operations through Composio's Parsera toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/parsera](https://composio.dev/toolkits/parsera)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Parsera connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `parsera`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `parsera`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Parsera operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Parsera task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"parsera\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Parsera-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `parsera` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/parseur-automation/SKILL.md",
    "content": "---\nname: parseur-automation\ndescription: \"Automate Parseur tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Parseur Automation via Rube MCP\n\nAutomate Parseur operations through Composio's Parseur toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/parseur](https://composio.dev/toolkits/parseur)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Parseur connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `parseur`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `parseur`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Parseur operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Parseur task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"parseur\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Parseur-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `parseur` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/passcreator-automation/SKILL.md",
    "content": "---\nname: passcreator-automation\ndescription: \"Automate Passcreator tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Passcreator Automation via Rube MCP\n\nAutomate Passcreator operations through Composio's Passcreator toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/passcreator](https://composio.dev/toolkits/passcreator)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Passcreator connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `passcreator`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `passcreator`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Passcreator operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Passcreator task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"passcreator\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Passcreator-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `passcreator` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/passslot-automation/SKILL.md",
    "content": "---\nname: passslot-automation\ndescription: \"Automate Passslot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Passslot Automation via Rube MCP\n\nAutomate Passslot operations through Composio's Passslot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/passslot](https://composio.dev/toolkits/passslot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Passslot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `passslot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `passslot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Passslot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Passslot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"passslot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Passslot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `passslot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/payhip-automation/SKILL.md",
    "content": "---\nname: payhip-automation\ndescription: \"Automate Payhip tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Payhip Automation via Rube MCP\n\nAutomate Payhip operations through Composio's Payhip toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/payhip](https://composio.dev/toolkits/payhip)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Payhip connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `payhip`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `payhip`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Payhip operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Payhip task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"payhip\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Payhip-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `payhip` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pdf-api-io-automation/SKILL.md",
    "content": "---\nname: pdf-api-io-automation\ndescription: \"Automate PDF API IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# PDF API IO Automation via Rube MCP\n\nAutomate PDF API IO operations through Composio's PDF API IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pdf_api_io](https://composio.dev/toolkits/pdf_api_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active PDF API IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_api_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_api_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"PDF API IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific PDF API IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pdf_api_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with PDF API IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_api_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pdf-co-automation/SKILL.md",
    "content": "---\nname: pdf-co-automation\ndescription: \"Automate PDF co tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# PDF co Automation via Rube MCP\n\nAutomate PDF co operations through Composio's PDF co toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pdf_co](https://composio.dev/toolkits/pdf_co)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active PDF co connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_co`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_co`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"PDF co operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific PDF co task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pdf_co\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with PDF co-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf_co` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pdf4me-automation/SKILL.md",
    "content": "---\nname: pdf4me-automation\ndescription: \"Automate Pdf4me tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pdf4me Automation via Rube MCP\n\nAutomate Pdf4me operations through Composio's Pdf4me toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pdf4me](https://composio.dev/toolkits/pdf4me)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pdf4me connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf4me`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf4me`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pdf4me operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pdf4me task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pdf4me\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pdf4me-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pdf4me` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pdfless-automation/SKILL.md",
    "content": "---\nname: pdfless-automation\ndescription: \"Automate Pdfless tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pdfless Automation via Rube MCP\n\nAutomate Pdfless operations through Composio's Pdfless toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pdfless](https://composio.dev/toolkits/pdfless)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pdfless connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfless`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfless`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pdfless operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pdfless task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pdfless\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pdfless-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfless` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pdfmonkey-automation/SKILL.md",
    "content": "---\nname: pdfmonkey-automation\ndescription: \"Automate Pdfmonkey tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pdfmonkey Automation via Rube MCP\n\nAutomate Pdfmonkey operations through Composio's Pdfmonkey toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pdfmonkey](https://composio.dev/toolkits/pdfmonkey)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pdfmonkey connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfmonkey`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfmonkey`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pdfmonkey operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pdfmonkey task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pdfmonkey\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pdfmonkey-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pdfmonkey` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/peopledatalabs-automation/SKILL.md",
    "content": "---\nname: peopledatalabs-automation\ndescription: \"Automate Peopledatalabs tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Peopledatalabs Automation via Rube MCP\n\nAutomate Peopledatalabs operations through Composio's Peopledatalabs toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/peopledatalabs](https://composio.dev/toolkits/peopledatalabs)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Peopledatalabs connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `peopledatalabs`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `peopledatalabs`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Peopledatalabs operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Peopledatalabs task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"peopledatalabs\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Peopledatalabs-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `peopledatalabs` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/perigon-automation/SKILL.md",
    "content": "---\nname: perigon-automation\ndescription: \"Automate Perigon tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Perigon Automation via Rube MCP\n\nAutomate Perigon operations through Composio's Perigon toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/perigon](https://composio.dev/toolkits/perigon)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Perigon connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `perigon`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `perigon`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Perigon operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Perigon task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"perigon\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Perigon-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `perigon` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/perplexityai-automation/SKILL.md",
    "content": "---\nname: perplexityai-automation\ndescription: \"Automate Perplexityai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Perplexityai Automation via Rube MCP\n\nAutomate Perplexityai operations through Composio's Perplexityai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/perplexityai](https://composio.dev/toolkits/perplexityai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Perplexityai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `perplexityai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `perplexityai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Perplexityai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Perplexityai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"perplexityai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Perplexityai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `perplexityai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/persistiq-automation/SKILL.md",
    "content": "---\nname: persistiq-automation\ndescription: \"Automate Persistiq tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Persistiq Automation via Rube MCP\n\nAutomate Persistiq operations through Composio's Persistiq toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/persistiq](https://composio.dev/toolkits/persistiq)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Persistiq connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `persistiq`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `persistiq`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Persistiq operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Persistiq task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"persistiq\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Persistiq-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `persistiq` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pexels-automation/SKILL.md",
    "content": "---\nname: pexels-automation\ndescription: \"Automate Pexels tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pexels Automation via Rube MCP\n\nAutomate Pexels operations through Composio's Pexels toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pexels](https://composio.dev/toolkits/pexels)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pexels connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pexels`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pexels`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pexels operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pexels task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pexels\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pexels-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pexels` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/phantombuster-automation/SKILL.md",
    "content": "---\nname: PhantomBuster Automation\ndescription: \"Automate lead generation, web scraping, and social media data extraction workflows through PhantomBuster's cloud platform via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# PhantomBuster Automation\n\nAutomate cloud-based data extraction and lead generation -- manage agents and scripts, monitor organization resources and usage, track container execution, and solve captcha challenges -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/phantombuster](https://composio.dev/toolkits/phantombuster)\n\n---\n\n## Setup\n\n1. Connect your PhantomBuster account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `PHANTOMBUSTER_*` tools become available for execution\n\n---\n\n## Core Workflows\n\n### 1. List All Agents\nFetch every agent associated with your account or organization to inventory automation workflows.\n\n**Tool:** `PHANTOMBUSTER_GET_AGENTS_FETCH_ALL`\n\n```\nNo parameters required -- returns all agents with IDs and metadata.\nAuthenticate your API key first.\n```\n\nUse agent IDs from this response when fetching containers or monitoring specific automations.\n\n---\n\n### 2. List All Scripts\nRetrieve all scripts available under your account (without code bodies) for script management.\n\n**Tool:** `PHANTOMBUSTER_GET_SCRIPTS_FETCH_ALL`\n\n```\nNo parameters required -- returns script metadata without source code.\n```\n\n---\n\n### 3. Monitor Organization Resources & Quotas\nCheck your organization's current resource usage and quota limits to plan automation capacity.\n\n**Tool:** `PHANTOMBUSTER_GET_ORGS_FETCH_RESOURCES`\n\n```\nNo parameters required -- returns resource allocation and current usage metrics.\n```\n\n---\n\n### 4. Retrieve Agent Containers\nFetch all execution containers for a specific agent to monitor run history and status.\n\n**Tool:** `PHANTOMBUSTER_GET_CONTAINERS_FETCH_ALL`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `agentId` | string | Yes | Agent ID from `PHANTOMBUSTER_GET_AGENTS_FETCH_ALL` |\n\n---\n\n### 5. Export Agent Usage Report\nDownload a CSV report of all agents' run statistics for your organization.\n\n**Tool:** `PHANTOMBUSTER_GET_ORGS_EXPORT_AGENT_USAGE`\n\n```\nReturns a downloadable CSV with comprehensive agent execution statistics.\n```\n\n---\n\n### 6. Solve hCaptcha Challenges\nObtain a valid hCaptcha token for automated form submissions or scraping flows that require captcha solving.\n\n**Tool:** `PHANTOMBUSTER_POST_HCAPTCHA`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `siteKey` | string | Yes | Public site key of the hCaptcha widget |\n| `pageUrl` | string | Yes | Full URL of the page with the captcha |\n| `proxy` | string | No | Proxy URL (e.g., `http://user:pass@host:port`) |\n| `userAgent` | string | No | Custom User-Agent string to simulate |\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Agent ID required for containers** | `PHANTOMBUSTER_GET_CONTAINERS_FETCH_ALL` requires a valid `agentId` -- always resolve it first via `PHANTOMBUSTER_GET_AGENTS_FETCH_ALL` |\n| **API key authentication** | All PhantomBuster tools require a valid API key connection -- verify authentication before calling any tools |\n| **Script bodies not included** | `PHANTOMBUSTER_GET_SCRIPTS_FETCH_ALL` returns metadata only, not source code |\n| **Organization scope** | Resource and usage tools operate at the organization level tied to your API key -- ensure the correct org is targeted |\n| **Branch operations** | `PHANTOMBUSTER_GET_BRANCHES_FETCH_ALL` and `PHANTOMBUSTER_GET_BRANCHES_DIFF` are for advanced script versioning -- use them to assess staging vs. release changes before deployment |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `PHANTOMBUSTER_GET_AGENTS_FETCH_ALL` | List all agents in your account |\n| `PHANTOMBUSTER_GET_SCRIPTS_FETCH_ALL` | List all scripts (metadata only) |\n| `PHANTOMBUSTER_GET_ORGS_FETCH_RESOURCES` | Check organization resource usage and quotas |\n| `PHANTOMBUSTER_GET_CONTAINERS_FETCH_ALL` | Get all containers for a specific agent |\n| `PHANTOMBUSTER_GET_ORGS_EXPORT_AGENT_USAGE` | Export agent usage as CSV |\n| `PHANTOMBUSTER_POST_HCAPTCHA` | Solve hCaptcha challenges for automation |\n| `PHANTOMBUSTER_GET_ORGS_FETCH` | Fetch organization details |\n| `PHANTOMBUSTER_GET_ORGS_FETCH_AGENT_GROUPS` | Get agent groups and ordering |\n| `PHANTOMBUSTER_GET_BRANCHES_FETCH_ALL` | List all script branches |\n| `PHANTOMBUSTER_GET_BRANCHES_DIFF` | Compare staging vs. release branches |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/piggy-automation/SKILL.md",
    "content": "---\nname: piggy-automation\ndescription: \"Automate Piggy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Piggy Automation via Rube MCP\n\nAutomate Piggy operations through Composio's Piggy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/piggy](https://composio.dev/toolkits/piggy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Piggy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `piggy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `piggy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Piggy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Piggy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"piggy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Piggy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `piggy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/piloterr-automation/SKILL.md",
    "content": "---\nname: piloterr-automation\ndescription: \"Automate Piloterr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Piloterr Automation via Rube MCP\n\nAutomate Piloterr operations through Composio's Piloterr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/piloterr](https://composio.dev/toolkits/piloterr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Piloterr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `piloterr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `piloterr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Piloterr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Piloterr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"piloterr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Piloterr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `piloterr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pilvio-automation/SKILL.md",
    "content": "---\nname: pilvio-automation\ndescription: \"Automate Pilvio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pilvio Automation via Rube MCP\n\nAutomate Pilvio operations through Composio's Pilvio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pilvio](https://composio.dev/toolkits/pilvio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pilvio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pilvio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pilvio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pilvio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pilvio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pilvio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pilvio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pilvio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pingdom-automation/SKILL.md",
    "content": "---\nname: pingdom-automation\ndescription: \"Automate Pingdom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pingdom Automation via Rube MCP\n\nAutomate Pingdom operations through Composio's Pingdom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pingdom](https://composio.dev/toolkits/pingdom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pingdom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pingdom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pingdom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pingdom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pingdom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pingdom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pingdom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pingdom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pipeline-crm-automation/SKILL.md",
    "content": "---\nname: pipeline-crm-automation\ndescription: \"Automate Pipeline CRM tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pipeline CRM Automation via Rube MCP\n\nAutomate Pipeline CRM operations through Composio's Pipeline CRM toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pipeline_crm](https://composio.dev/toolkits/pipeline_crm)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pipeline CRM connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pipeline_crm`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pipeline_crm`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pipeline CRM operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pipeline CRM task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pipeline_crm\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pipeline CRM-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pipeline_crm` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/placekey-automation/SKILL.md",
    "content": "---\nname: placekey-automation\ndescription: \"Automate Placekey tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Placekey Automation via Rube MCP\n\nAutomate Placekey operations through Composio's Placekey toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/placekey](https://composio.dev/toolkits/placekey)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Placekey connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `placekey`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `placekey`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Placekey operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Placekey task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"placekey\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Placekey-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `placekey` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/placid-automation/SKILL.md",
    "content": "---\nname: placid-automation\ndescription: \"Automate Placid tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Placid Automation via Rube MCP\n\nAutomate Placid operations through Composio's Placid toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/placid](https://composio.dev/toolkits/placid)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Placid connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `placid`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `placid`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Placid operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Placid task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"placid\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Placid-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `placid` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/plain-automation/SKILL.md",
    "content": "---\nname: plain-automation\ndescription: \"Automate Plain tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Plain Automation via Rube MCP\n\nAutomate Plain operations through Composio's Plain toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/plain](https://composio.dev/toolkits/plain)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Plain connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `plain`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `plain`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Plain operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Plain task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"plain\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Plain-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `plain` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/plasmic-automation/SKILL.md",
    "content": "---\nname: plasmic-automation\ndescription: \"Automate Plasmic tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Plasmic Automation via Rube MCP\n\nAutomate Plasmic operations through Composio's Plasmic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/plasmic](https://composio.dev/toolkits/plasmic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Plasmic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `plasmic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `plasmic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Plasmic operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Plasmic task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"plasmic\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Plasmic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `plasmic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/platerecognizer-automation/SKILL.md",
    "content": "---\nname: platerecognizer-automation\ndescription: \"Automate Platerecognizer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Platerecognizer Automation via Rube MCP\n\nAutomate Platerecognizer operations through Composio's Platerecognizer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/platerecognizer](https://composio.dev/toolkits/platerecognizer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Platerecognizer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `platerecognizer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `platerecognizer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Platerecognizer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Platerecognizer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"platerecognizer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Platerecognizer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `platerecognizer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/plisio-automation/SKILL.md",
    "content": "---\nname: plisio-automation\ndescription: \"Automate Plisio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Plisio Automation via Rube MCP\n\nAutomate Plisio operations through Composio's Plisio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/plisio](https://composio.dev/toolkits/plisio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Plisio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `plisio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `plisio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Plisio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Plisio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"plisio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Plisio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `plisio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/polygon-automation/SKILL.md",
    "content": "---\nname: polygon-automation\ndescription: \"Automate Polygon tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Polygon Automation via Rube MCP\n\nAutomate Polygon operations through Composio's Polygon toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/polygon](https://composio.dev/toolkits/polygon)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Polygon connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Polygon operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Polygon task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"polygon\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Polygon-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/polygon-io-automation/SKILL.md",
    "content": "---\nname: polygon-io-automation\ndescription: \"Automate Polygon IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Polygon IO Automation via Rube MCP\n\nAutomate Polygon IO operations through Composio's Polygon IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/polygon_io](https://composio.dev/toolkits/polygon_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Polygon IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Polygon IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Polygon IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"polygon_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Polygon IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `polygon_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/poptin-automation/SKILL.md",
    "content": "---\nname: poptin-automation\ndescription: \"Automate Poptin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Poptin Automation via Rube MCP\n\nAutomate Poptin operations through Composio's Poptin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/poptin](https://composio.dev/toolkits/poptin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Poptin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `poptin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `poptin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Poptin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Poptin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"poptin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Poptin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `poptin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/postgrid-automation/SKILL.md",
    "content": "---\nname: postgrid-automation\ndescription: \"Automate Postgrid tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Postgrid Automation via Rube MCP\n\nAutomate Postgrid operations through Composio's Postgrid toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/postgrid](https://composio.dev/toolkits/postgrid)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Postgrid connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Postgrid operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Postgrid task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"postgrid\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Postgrid-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/postgrid-verify-automation/SKILL.md",
    "content": "---\nname: postgrid-verify-automation\ndescription: \"Automate Postgrid Verify tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Postgrid Verify Automation via Rube MCP\n\nAutomate Postgrid Verify operations through Composio's Postgrid Verify toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/postgrid_verify](https://composio.dev/toolkits/postgrid_verify)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Postgrid Verify connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid_verify`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid_verify`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Postgrid Verify operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Postgrid Verify task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"postgrid_verify\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Postgrid Verify-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `postgrid_verify` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/precoro-automation/SKILL.md",
    "content": "---\nname: precoro-automation\ndescription: \"Automate Precoro tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Precoro Automation via Rube MCP\n\nAutomate Precoro operations through Composio's Precoro toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/precoro](https://composio.dev/toolkits/precoro)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Precoro connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `precoro`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `precoro`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Precoro operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Precoro task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"precoro\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Precoro-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `precoro` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/prerender-automation/SKILL.md",
    "content": "---\nname: prerender-automation\ndescription: \"Automate Prerender tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Prerender Automation via Rube MCP\n\nAutomate Prerender operations through Composio's Prerender toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/prerender](https://composio.dev/toolkits/prerender)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Prerender connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `prerender`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `prerender`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Prerender operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Prerender task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"prerender\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Prerender-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `prerender` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/printautopilot-automation/SKILL.md",
    "content": "---\nname: printautopilot-automation\ndescription: \"Automate Printautopilot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Printautopilot Automation via Rube MCP\n\nAutomate Printautopilot operations through Composio's Printautopilot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/printautopilot](https://composio.dev/toolkits/printautopilot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Printautopilot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `printautopilot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `printautopilot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Printautopilot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Printautopilot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"printautopilot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Printautopilot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `printautopilot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/prisma-automation/SKILL.md",
    "content": "---\nname: prisma-automation\ndescription: \"Automate Prisma tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Prisma Automation via Rube MCP\n\nAutomate Prisma operations through Composio's Prisma toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/prisma](https://composio.dev/toolkits/prisma)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Prisma connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `prisma`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `prisma`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Prisma operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Prisma task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"prisma\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Prisma-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `prisma` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/prismic-automation/SKILL.md",
    "content": "---\nname: Prismic Automation\ndescription: \"Automate headless CMS operations in Prismic -- query documents, search content, retrieve custom types, and manage repository refs through the Composio Prismic integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Prismic Automation\n\nManage your **Prismic** headless CMS directly from Claude Code. Query documents by type, full-text search content, inspect custom types, and work with repository refs for content versioning.\n\n**Toolkit docs:** [composio.dev/toolkits/prismic](https://composio.dev/toolkits/prismic)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your Prismic account when prompted. The agent will provide an authentication link.\n3. Most content queries require a `ref` token. Always start by calling `PRISMIC_REPOSITORY_API_GET_REFS` or `PRISMIC_REPOSITORY_API_GET_INFO` to obtain the master ref.\n\n---\n\n## Core Workflows\n\n### 1. Get Repository Info and Refs\n\nRetrieve comprehensive repository metadata including available refs (content versions), custom types, languages, tags, and bookmarks. This is typically your first API call.\n\n**Tools:** `PRISMIC_REPOSITORY_API_GET_INFO`, `PRISMIC_REPOSITORY_API_GET_REFS`\n\nNo parameters required -- these endpoints return the full repository configuration. The `refs` field is critical since refs are required for all content queries.\n\nExample prompt: *\"Get my Prismic repository info and the current master ref\"*\n\n---\n\n### 2. Query Documents with Predicates\n\nFetch documents using Prismic's predicate query syntax with full pagination and filtering support.\n\n**Tool:** `PRISMIC_CONTENT_API_QUERY_DOCUMENTS`\n\nKey parameters:\n- `ref` (required) -- content release reference ID (typically the master ref)\n- `q` -- predicate query, e.g., `[[at(document.type, \"page\")]]`\n- `page` (min 1) and `pageSize` (1-100) -- pagination\n- `lang` -- language code, e.g., `en-us` (default `*` for all)\n- `orderings` -- sort order, e.g., `[my.article.date desc]`\n- `fetch` -- comma-separated fields to fetch, reducing response size\n- `fetchLinks` -- resolve linked document fields inline\n\nExample prompt: *\"Query all published blog posts in Prismic, sorted by date descending, in English\"*\n\n---\n\n### 3. Fetch Documents by Type\n\nRetrieve all documents of a specific custom type with automatic master ref resolution.\n\n**Tool:** `PRISMIC_GET_DOCUMENTS_BY_TYPE`\n\nKey parameters:\n- `type` (required) -- custom type API ID, e.g., `blog_post`, `article`, `page`\n- `page` (default 1) and `pageSize` (1-100, default 20)\n- `lang` -- language code filter\n- `orderings` -- sort order, e.g., `[my.article.date desc]`\n- `after` -- cursor-based pagination for deep pagination beyond page 50\n\nExample prompt: *\"Get all blog_post documents in Prismic, 20 per page\"*\n\n---\n\n### 4. Full-Text Search\n\nSearch across all text fields in documents for specified terms. Case-insensitive, matches on root words.\n\n**Tool:** `PRISMIC_CONTENT_API_GET_DOCUMENTS_WITH_FULLTEXT_SEARCH`\n\nKey parameters:\n- `q` (required) -- full-text predicate, e.g., `[[fulltext(document, \"machine learning\")]]`\n- `page`, `pageSize`, `lang`, `orderings` -- same pagination/filtering as other queries\n\nExample prompt: *\"Search all Prismic documents for 'machine learning'\"*\n\n---\n\n### 5. Get a Single Document by ID\n\nRetrieve a specific document by its unique identifier.\n\n**Tool:** `PRISMIC_GET_DOCUMENT_BY_ID`\n\nKey parameters:\n- `document_id` (required) -- unique document identifier\n- `ref` (required) -- content ref from repository\n- `lang` -- optional language filter\n\nExample prompt: *\"Fetch Prismic document Xx2KLhEAAJljVWaA\"*\n\n---\n\n### 6. List Custom Types\n\nDiscover all custom types (content models) defined in the repository, including their structure definitions.\n\n**Tool:** `PRISMIC_TYPES_API_GET_TYPES`\n\nKey parameters:\n- `limit` -- max number of types to return per page\n- `page` -- page number (1-indexed)\n- `sort` -- sort order, e.g., `name`\n\nExample prompt: *\"List all custom types in my Prismic repository\"*\n\n---\n\n## Known Pitfalls\n\n- **Ref is required for all content queries:** You must obtain a valid `ref` (typically the master ref) from `PRISMIC_REPOSITORY_API_GET_REFS` or `PRISMIC_REPOSITORY_API_GET_INFO` before querying any documents. Queries without a ref will fail.\n- **Predicate syntax requires double brackets:** Prismic queries use double square brackets: `[[at(document.type, \"page\")]]`. For multiple predicates, combine them: `[[at(document.type, \"blog\")][at(document.tags, [\"featured\"])]]`.\n- **Deep pagination limit:** Standard page-based pagination may fail beyond page 50. For deep pagination, use the `after` parameter with the last document ID from your previous result set.\n- **pageSize cap is 100:** Requesting more than 100 documents per page will be rejected. Use pagination to iterate through larger result sets.\n- **Language filtering:** The default language filter is `*` (all languages). If you need documents in a specific locale, always pass `lang` explicitly (e.g., `en-us`, `fr-fr`).\n- **Integration fields require separate ref:** When using `PRISMIC_CONTENT_API_GET_DOCUMENTS_WITH_INTEGRATION_FIELDS`, you need an `integrationFieldsRef` in addition to the standard content `ref`.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `PRISMIC_REPOSITORY_API_GET_INFO` | Get repository metadata, refs, types, languages |\n| `PRISMIC_REPOSITORY_API_GET_REFS` | List all refs (master + releases) |\n| `PRISMIC_TYPES_API_GET_TYPES` | List all custom types / content models |\n| `PRISMIC_CONTENT_API_QUERY_DOCUMENTS` | Query documents with predicates and pagination |\n| `PRISMIC_GET_DOCUMENTS_BY_TYPE` | Fetch documents filtered by custom type |\n| `PRISMIC_GET_DOCUMENT_BY_ID` | Retrieve a single document by ID |\n| `PRISMIC_CONTENT_API_GET_DOCUMENTS_WITH_FULLTEXT_SEARCH` | Full-text search across all documents |\n| `PRISMIC_CONTENT_API_GET_DOCUMENTS_WITH_PREDICATES` | Filter documents with multiple predicate conditions |\n| `PRISMIC_CONTENT_API_GET_DOCUMENTS_WITH_INTEGRATION_FIELDS` | Fetch documents with integration fields data |\n| `PRISMIC_GET_DOCUMENTS_ORDERED` | Fetch documents sorted by specified fields |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/process-street-automation/SKILL.md",
    "content": "---\nname: process-street-automation\ndescription: \"Automate Process Street tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Process Street Automation via Rube MCP\n\nAutomate Process Street operations through Composio's Process Street toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/process_street](https://composio.dev/toolkits/process_street)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Process Street connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `process_street`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `process_street`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Process Street operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Process Street task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"process_street\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Process Street-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `process_street` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/procfu-automation/SKILL.md",
    "content": "---\nname: procfu-automation\ndescription: \"Automate Procfu tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Procfu Automation via Rube MCP\n\nAutomate Procfu operations through Composio's Procfu toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/procfu](https://composio.dev/toolkits/procfu)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Procfu connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `procfu`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `procfu`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Procfu operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Procfu task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"procfu\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Procfu-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `procfu` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/productboard-automation/SKILL.md",
    "content": "---\nname: Productboard Automation\ndescription: \"Automate product management workflows in Productboard -- manage features, notes, objectives, components, and releases through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Productboard Automation\n\nAutomate your Productboard product management operations directly from Claude Code. Create notes from customer feedback, browse features and objectives, link entities, and track releases -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/productboard](https://composio.dev/toolkits/productboard)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Productboard account through the connection link provided\n3. Start automating your product management workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Manage Customer Notes\n\nCreate notes from customer feedback and organize them with tags, links, and followers.\n\n**Tools:** `PRODUCTBOARD_CREATE_NOTE`, `PRODUCTBOARD_LIST_NOTES`, `PRODUCTBOARD_ADD_NOTE_TAG`, `PRODUCTBOARD_ADD_NOTE_FOLLOWERS`, `PRODUCTBOARD_CREATE_NOTE_LINK`\n\n```\nCreate a note titled \"Mobile app crash report\" with content from customer feedback, tagged \"bug\" and linked to feature abc-123\n```\n\nKey parameters for `PRODUCTBOARD_CREATE_NOTE`:\n- `title` (required) and `content` (required) -- note title and body\n- `customer_email` or `user.email` -- attribute to a customer/user\n- `tags` -- array of tag strings for categorization\n- `display_url` -- URL linked from the note title\n- `source` -- origin system with `origin` and `record_id`\n- `company` -- associate with a company\n\nKey parameters for `PRODUCTBOARD_LIST_NOTES`:\n- `createdFrom` / `createdTo` -- ISO 8601 date range\n- `last` -- relative time window (e.g., `\"6m\"`, `\"10d\"`, `\"24h\"`)\n- `term` -- full-text search by title or content\n- `allTags` / `anyTag` -- filter by tags (cannot combine both)\n- `featureId`, `companyId`, `ownerEmail`, `source` -- entity filters\n- `pageLimit` (max 100) / `pageCursor` -- pagination\n\n### 2. Browse and Retrieve Features\n\nList all features/subfeatures and retrieve detailed information.\n\n**Tools:** `PRODUCTBOARD_LIST_FEATURES`, `PRODUCTBOARD_RETRIEVE_FEATURE`\n\n```\nList the first 50 features in Productboard, then get details on feature abc-def-123\n```\n\n- `PRODUCTBOARD_LIST_FEATURES` supports `pageLimit` (default 100) and `pageOffset` for pagination\n- `PRODUCTBOARD_RETRIEVE_FEATURE` requires feature `id` (UUID) to get complete details\n\n### 3. Objectives and Key Results (OKRs)\n\nList objectives, view feature-objective links, and browse key results.\n\n**Tools:** `PRODUCTBOARD_LIST_OBJECTIVES`, `PRODUCTBOARD_LIST_FEATURE_OBJECTIVES`, `PRODUCTBOARD_LIST_KEY_RESULTS`\n\n```\nShow me all in-progress objectives owned by alice@example.com\n```\n\nKey parameters for `PRODUCTBOARD_LIST_OBJECTIVES`:\n- `status.name` -- filter by status (e.g., `\"In Progress\"`)\n- `owner.email` -- filter by owner email\n- `parent.id` -- filter by parent objective\n- `archived` -- filter by archived state\n\n`PRODUCTBOARD_LIST_FEATURE_OBJECTIVES`:\n- Requires `id` (UUID) of a **top-level feature** (not subfeatures)\n- Supports `pageCursor` for pagination\n\n### 4. Component Management\n\nList product components for organizing features and the product hierarchy.\n\n**Tool:** `PRODUCTBOARD_LIST_COMPONENTS`\n\n```\nList all components in our Productboard workspace\n```\n\n- Supports `page_limit` and `page_offset` for pagination\n- Follow `links.next` for additional pages\n\n### 5. Release Tracking\n\nView feature-release assignments with state and date filters.\n\n**Tool:** `PRODUCTBOARD_LIST_FEATURE_RELEASE_ASSIGNMENTS`\n\n```\nShow all active release assignments for feature abc-123\n```\n\n- Filter by `feature.id`, `release.id`, `release.state` (planned, active, closed)\n- Date range filters: `release.timeframe.endDate.from` and `release.timeframe.endDate.to` (YYYY-MM-DD)\n\n### 6. Link Notes to Features\n\nConnect customer feedback notes to product features for insight aggregation.\n\n**Tool:** `PRODUCTBOARD_CREATE_NOTE_LINK`\n\n```\nLink note 3fa85f64-5717 to feature 1b6c8c76-8f5d for tracking\n```\n\n- Requires `noteId` (UUID) and `entityId` (UUID of feature, component, or product)\n- Use after creating notes to ensure feedback is connected to the right product areas\n\n---\n\n## Known Pitfalls\n\n- **Top-level features only for objectives:** `PRODUCTBOARD_LIST_FEATURE_OBJECTIVES` only works with top-level feature IDs, not subfeature IDs. Use `PRODUCTBOARD_LIST_FEATURES` to identify which features are top-level.\n- **Tag filter exclusivity:** `allTags` and `anyTag` cannot be combined in `PRODUCTBOARD_LIST_NOTES`. Choose one filter strategy per query.\n- **Relative vs. absolute dates:** The `last` parameter (e.g., `\"24h\"`) cannot be combined with `createdFrom`/`createdTo` in `PRODUCTBOARD_LIST_NOTES`. Use one approach, not both.\n- **Cursor-based pagination:** Follow `links.next` or use `pageCursor` from responses for multi-page results. Offset-based and cursor-based pagination are used on different endpoints -- check each tool.\n- **Note attribution:** Either `user.email` or `customer_email` must be provided in `PRODUCTBOARD_CREATE_NOTE` to attribute feedback. Without it, the note will have no customer association.\n- **UUID formats required:** All entity IDs (features, notes, components) must be valid UUIDs. Passing malformed IDs causes 400 errors.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `PRODUCTBOARD_CREATE_NOTE` | Create a customer feedback note (requires `title`, `content`) |\n| `PRODUCTBOARD_LIST_NOTES` | List notes with search, date, and tag filters |\n| `PRODUCTBOARD_ADD_NOTE_TAG` | Add a tag to a note |\n| `PRODUCTBOARD_ADD_NOTE_FOLLOWERS` | Add followers to a note by email |\n| `PRODUCTBOARD_CREATE_NOTE_LINK` | Link a note to a feature/component (requires `noteId`, `entityId`) |\n| `PRODUCTBOARD_LIST_FEATURES` | List all features with pagination |\n| `PRODUCTBOARD_RETRIEVE_FEATURE` | Get detailed feature info by UUID |\n| `PRODUCTBOARD_LIST_OBJECTIVES` | List objectives with status/owner filters |\n| `PRODUCTBOARD_LIST_FEATURE_OBJECTIVES` | List objectives linked to a top-level feature |\n| `PRODUCTBOARD_LIST_KEY_RESULTS` | List key results for objectives |\n| `PRODUCTBOARD_LIST_COMPONENTS` | List product components with pagination |\n| `PRODUCTBOARD_LIST_FEATURE_RELEASE_ASSIGNMENTS` | List feature-release assignments with filters |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/productlane-automation/SKILL.md",
    "content": "---\nname: productlane-automation\ndescription: \"Automate Productlane tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Productlane Automation via Rube MCP\n\nAutomate Productlane operations through Composio's Productlane toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/productlane](https://composio.dev/toolkits/productlane)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Productlane connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `productlane`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `productlane`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Productlane operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Productlane task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"productlane\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Productlane-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `productlane` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/project-bubble-automation/SKILL.md",
    "content": "---\nname: project-bubble-automation\ndescription: \"Automate Project Bubble tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Project Bubble Automation via Rube MCP\n\nAutomate Project Bubble operations through Composio's Project Bubble toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/project_bubble](https://composio.dev/toolkits/project_bubble)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Project Bubble connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `project_bubble`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `project_bubble`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Project Bubble operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Project Bubble task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"project_bubble\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Project Bubble-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `project_bubble` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/proofly-automation/SKILL.md",
    "content": "---\nname: proofly-automation\ndescription: \"Automate Proofly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Proofly Automation via Rube MCP\n\nAutomate Proofly operations through Composio's Proofly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/proofly](https://composio.dev/toolkits/proofly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Proofly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `proofly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `proofly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Proofly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Proofly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"proofly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Proofly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `proofly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/proxiedmail-automation/SKILL.md",
    "content": "---\nname: proxiedmail-automation\ndescription: \"Automate Proxiedmail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Proxiedmail Automation via Rube MCP\n\nAutomate Proxiedmail operations through Composio's Proxiedmail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/proxiedmail](https://composio.dev/toolkits/proxiedmail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Proxiedmail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `proxiedmail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `proxiedmail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Proxiedmail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Proxiedmail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"proxiedmail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Proxiedmail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `proxiedmail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pushbullet-automation/SKILL.md",
    "content": "---\nname: pushbullet-automation\ndescription: \"Automate Pushbullet tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pushbullet Automation via Rube MCP\n\nAutomate Pushbullet operations through Composio's Pushbullet toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pushbullet](https://composio.dev/toolkits/pushbullet)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pushbullet connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pushbullet`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pushbullet`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pushbullet operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pushbullet task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pushbullet\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pushbullet-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pushbullet` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/pushover-automation/SKILL.md",
    "content": "---\nname: pushover-automation\ndescription: \"Automate Pushover tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Pushover Automation via Rube MCP\n\nAutomate Pushover operations through Composio's Pushover toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/pushover](https://composio.dev/toolkits/pushover)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Pushover connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `pushover`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `pushover`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Pushover operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Pushover task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"pushover\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Pushover-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `pushover` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/quaderno-automation/SKILL.md",
    "content": "---\nname: quaderno-automation\ndescription: \"Automate Quaderno tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Quaderno Automation via Rube MCP\n\nAutomate Quaderno operations through Composio's Quaderno toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/quaderno](https://composio.dev/toolkits/quaderno)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Quaderno connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `quaderno`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `quaderno`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Quaderno operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Quaderno task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"quaderno\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Quaderno-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `quaderno` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/qualaroo-automation/SKILL.md",
    "content": "---\nname: qualaroo-automation\ndescription: \"Automate Qualaroo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Qualaroo Automation via Rube MCP\n\nAutomate Qualaroo operations through Composio's Qualaroo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/qualaroo](https://composio.dev/toolkits/qualaroo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Qualaroo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `qualaroo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `qualaroo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Qualaroo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Qualaroo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"qualaroo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Qualaroo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `qualaroo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/quickbooks-automation/SKILL.md",
    "content": "---\nname: QuickBooks Automation\ndescription: \"QuickBooks Automation: manage invoices, customers, accounts, and payments in QuickBooks Online for streamlined bookkeeping\"\nrequires:\n  mcp: [rube]\n---\n\n# QuickBooks Automation\n\nAutomate QuickBooks Online operations including creating invoices, managing customers, querying accounts, and listing invoices for financial reporting.\n\n**Toolkit docs:** [composio.dev/toolkits/quickbooks](https://composio.dev/toolkits/quickbooks)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `quickbooks` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. Create an Invoice\n\nCreate a new invoice for a customer with line items.\n\n**Tool:** `QUICKBOOKS_CREATE_INVOICE`\n\n**Key Parameters:**\n- `customer_id` (required) -- ID of the customer (CustomerRef.value)\n- `lines` (required) -- Array of line item objects. Each must include:\n  - `DetailType` -- e.g., `\"SalesItemLineDetail\"`\n  - `Amount` -- Line item total\n  - `SalesItemLineDetail` -- Object with `ItemRef` containing `value` (item ID)\n- `minorversion` -- Optional API version parameter\n\n**Example:**\n```\nTool: QUICKBOOKS_CREATE_INVOICE\nArguments:\n  customer_id: \"21\"\n  lines: [\n    {\n      \"DetailType\": \"SalesItemLineDetail\",\n      \"Amount\": 150.00,\n      \"SalesItemLineDetail\": {\n        \"ItemRef\": {\"value\": \"1\", \"name\": \"Services\"}\n      }\n    }\n  ]\n```\n\n**Prerequisites:** Resolve the customer ID using `QUICKBOOKS_READ_CUSTOMER` or create one with `QUICKBOOKS_CREATE_CUSTOMER`. Resolve item/account IDs using `QUICKBOOKS_QUERY_ACCOUNT`.\n\n---\n\n### 2. Manage Customers\n\nCreate and read customer records.\n\n**Tools:**\n- `QUICKBOOKS_CREATE_CUSTOMER` -- Create a new customer\n- `QUICKBOOKS_READ_CUSTOMER` -- Read a customer by ID\n\n**Key Parameters for `QUICKBOOKS_CREATE_CUSTOMER`:**\n- `display_name` -- Display name (must be unique across customers, vendors, employees; max 500 chars)\n- `given_name` -- First name (max 100 chars)\n- `family_name` -- Last name (max 100 chars)\n- `middle_name` -- Middle name (max 100 chars)\n- `title` -- Title, e.g., `\"Mr.\"`, `\"Dr.\"` (max 16 chars)\n- `suffix` -- Name suffix, e.g., `\"Jr.\"` (max 16 chars)\n\n> At least one of `display_name`, `title`, `given_name`, `middle_name`, `family_name`, or `suffix` is required.\n\n**Key Parameters for `QUICKBOOKS_READ_CUSTOMER`:**\n- `customer_id` (required) -- ID of the customer to read\n\n**Example:**\n```\nTool: QUICKBOOKS_CREATE_CUSTOMER\nArguments:\n  display_name: \"Acme Corporation\"\n  given_name: \"John\"\n  family_name: \"Doe\"\n```\n\n---\n\n### 3. Query and Read Accounts\n\nRetrieve account information for use in invoice line items and financial reporting.\n\n**Tools:**\n- `QUICKBOOKS_QUERY_ACCOUNT` -- Execute a query against accounts\n- `QUICKBOOKS_READ_ACCOUNT` -- Read a specific account by ID\n\n**Key Parameters for `QUICKBOOKS_QUERY_ACCOUNT`:**\n- `query` (required) -- SQL-like query string, e.g., `\"SELECT * FROM Account WHERE AccountType = 'Income'\"`\n\n**Example:**\n```\nTool: QUICKBOOKS_QUERY_ACCOUNT\nArguments:\n  query: \"SELECT * FROM Account WHERE AccountType = 'Income' MAXRESULTS 10\"\n```\n\n---\n\n### 4. List and Filter Invoices\n\nRetrieve invoices with optional pagination and filtering.\n\n**Tool:** `QUICKBOOKS_LIST_INVOICES`\n\n**Steps:**\n1. Call `QUICKBOOKS_LIST_INVOICES` with pagination parameters\n2. Use `start_position` and `max_results` to page through results\n3. Filter by specific criteria as needed\n\n---\n\n## Recommended Execution Plan\n\n1. **Resolve the customer** using `QUICKBOOKS_READ_CUSTOMER` (if you have a customer ID) or create one with `QUICKBOOKS_CREATE_CUSTOMER`\n2. **Resolve item/revenue accounts** using `QUICKBOOKS_QUERY_ACCOUNT` and `QUICKBOOKS_READ_ACCOUNT` to get account or item IDs for invoice line items\n3. **Create the invoice** using `QUICKBOOKS_CREATE_INVOICE` with the resolved `customer_id` and well-formed line items\n4. **Verify creation** using `QUICKBOOKS_LIST_INVOICES` to locate the new invoice by ID or DocNumber\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Invalid references** | `QUICKBOOKS_CREATE_INVOICE` fails if `customer_id` or `ItemRef.value` point to non-existent or inactive records. Always resolve IDs first. |\n| **Line item validation** | Incorrect `DetailType` or missing `SalesItemLineDetail` fields cause schema/validation errors during invoice creation. |\n| **Pagination** | `QUICKBOOKS_LIST_INVOICES` uses `start_position` and `max_results`. Incomplete pagination settings can miss invoices in larger books. |\n| **Sync tokens** | Any later edits require the latest `SyncToken` from a fresh invoice read. Stale sync tokens cause update rejections. |\n| **Rate limits** | QuickBooks enforces per-minute and daily API caps. High-volume runs should include backoff to avoid throttling errors. |\n| **DisplayName uniqueness** | Customer `display_name` must be unique across all Customer, Vendor, and Employee objects. Duplicates cause creation failures. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `QUICKBOOKS_CREATE_INVOICE` | Create a new invoice with line items |\n| `QUICKBOOKS_READ_CUSTOMER` | Read a customer record by ID |\n| `QUICKBOOKS_CREATE_CUSTOMER` | Create a new customer record |\n| `QUICKBOOKS_QUERY_ACCOUNT` | Query accounts with SQL-like syntax |\n| `QUICKBOOKS_READ_ACCOUNT` | Read a specific account by ID |\n| `QUICKBOOKS_LIST_INVOICES` | List invoices with pagination |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/radar-automation/SKILL.md",
    "content": "---\nname: radar-automation\ndescription: \"Automate Radar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Radar Automation via Rube MCP\n\nAutomate Radar operations through Composio's Radar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/radar](https://composio.dev/toolkits/radar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Radar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `radar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `radar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Radar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Radar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"radar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Radar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `radar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rafflys-automation/SKILL.md",
    "content": "---\nname: rafflys-automation\ndescription: \"Automate Rafflys tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rafflys Automation via Rube MCP\n\nAutomate Rafflys operations through Composio's Rafflys toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rafflys](https://composio.dev/toolkits/rafflys)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rafflys connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rafflys`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rafflys`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rafflys operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rafflys task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rafflys\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rafflys-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rafflys` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ragic-automation/SKILL.md",
    "content": "---\nname: ragic-automation\ndescription: \"Automate Ragic tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ragic Automation via Rube MCP\n\nAutomate Ragic operations through Composio's Ragic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ragic](https://composio.dev/toolkits/ragic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ragic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ragic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ragic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ragic operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ragic task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ragic\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ragic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ragic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/raisely-automation/SKILL.md",
    "content": "---\nname: raisely-automation\ndescription: \"Automate Raisely tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Raisely Automation via Rube MCP\n\nAutomate Raisely operations through Composio's Raisely toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/raisely](https://composio.dev/toolkits/raisely)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Raisely connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `raisely`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `raisely`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Raisely operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Raisely task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"raisely\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Raisely-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `raisely` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ramp-automation/SKILL.md",
    "content": "---\nname: Ramp Automation\ndescription: \"Ramp Automation: manage corporate card transactions, reimbursements, users, and expense tracking via the Ramp platform\"\nrequires:\n  mcp: [rube]\n---\n\n# Ramp Automation\n\nAutomate Ramp corporate finance operations including retrieving transactions, managing reimbursements, searching expenses, viewing card details, and listing users for expense management and accounting workflows.\n\n**Toolkit docs:** [composio.dev/toolkits/ramp](https://composio.dev/toolkits/ramp)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `ramp` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n---\n\n## Core Workflows\n\n### 1. List All Transactions\n\nRetrieve all corporate card transactions with comprehensive filtering options.\n\n**Tool:** `RAMP_GET_ALL_TRANSACTIONS`\n\n**Key Parameters:**\n- `from_date` -- Transactions after this date (ISO 8601 datetime)\n- `to_date` -- Transactions before this date (ISO 8601 datetime, default: today)\n- `user_id` -- Filter by user UUID\n- `card_id` -- Filter by physical card UUID\n- `department_id` -- Filter by department UUID\n- `merchant_id` -- Filter by merchant UUID\n- `entity_id` -- Filter by business entity UUID\n- `min_amount` / `max_amount` -- Amount range filter (USD)\n- `state` -- Transaction state; set to `\"ALL\"` to include declined transactions\n- `approval_status` -- Filter by approval status\n- `sync_status` -- Filter by ERP sync status (supersedes `sync_ready` and `has_no_sync_commits`)\n- `has_no_sync_commits` -- `true` for unsynced transactions\n- `sync_ready` -- `true` for transactions ready to sync to ERP\n- `requires_memo` -- `true` for transactions missing required memos\n- `include_merchant_data` -- `true` to include full purchase data from merchant\n- `page_size` -- Results per page (2--100, default: 20)\n- `start` -- Pagination cursor: ID of last entity from previous page\n- `order_by_date_desc` / `order_by_date_asc` -- Sort by date\n- `order_by_amount_desc` / `order_by_amount_asc` -- Sort by amount\n\n**Example:**\n```\nTool: RAMP_GET_ALL_TRANSACTIONS\nArguments:\n  from_date: \"2026-02-01T00:00:00Z\"\n  to_date: \"2026-02-11T23:59:59Z\"\n  page_size: 50\n  order_by_date_desc: true\n```\n\n---\n\n### 2. Search Transactions\n\nSearch transactions by merchant name, memo, or other transaction details.\n\n**Tool:** `RAMP_SEARCH_TRANSACTIONS`\n\n**Key Parameters:**\n- `query` (required) -- Search text for merchant name, memo, or other details\n- All filter parameters from `RAMP_GET_ALL_TRANSACTIONS` are also available\n\n**Example:**\n```\nTool: RAMP_SEARCH_TRANSACTIONS\nArguments:\n  query: \"AWS\"\n  from_date: \"2026-01-01T00:00:00Z\"\n  page_size: 25\n```\n\n---\n\n### 3. Get Transaction Details\n\nRetrieve complete details of a specific transaction including merchant details, receipts, accounting codes, and dispute information.\n\n**Tool:** `RAMP_GET_TRANSACTION`\n\n**Key Parameters:**\n- `transaction_id` (required) -- ID of the transaction\n\n**Example:**\n```\nTool: RAMP_GET_TRANSACTION\nArguments:\n  transaction_id: \"txn_abc123def456\"\n```\n\n---\n\n### 4. Manage Reimbursements\n\nList and retrieve reimbursement records for approval workflows and expense analysis.\n\n**Tools:**\n- `RAMP_LIST_REIMBURSEMENTS` -- List reimbursements with filtering\n- `RAMP_GET_REIMBURSEMENT` -- Get complete details of a specific reimbursement\n\n**Key Parameters for `RAMP_LIST_REIMBURSEMENTS`:**\n- `user_id` -- Filter by employee UUID\n- `entity_id` -- Filter by business entity UUID\n- `from_date` / `to_date` -- Date range for creation date\n- `from_submitted_at` / `to_submitted_at` -- Date range for submission date\n- `from_transaction_date` / `to_transaction_date` -- Underlying transaction date range\n- `awaiting_approval_by_user_id` -- Filter for reimbursements pending a specific approver\n- `sync_status` -- Filter by ERP sync status\n- `has_no_sync_commits` -- `true` for unsynced reimbursements\n- `sync_ready` -- `true` for reimbursements ready to sync\n- `direction` -- `\"BUSINESS_TO_USER\"` (default) or `\"USER_TO_BUSINESS\"` (repayments)\n- `page_size` -- Results per page (2--100, default: 20)\n- `start` -- Pagination cursor\n\n**Example:**\n```\nTool: RAMP_LIST_REIMBURSEMENTS\nArguments:\n  from_date: \"2026-02-01T00:00:00Z\"\n  sync_ready: true\n  page_size: 50\n```\n\n---\n\n### 5. List Users and Get My Transactions\n\nView organization users and personal transaction history.\n\n**Tools:**\n- `RAMP_LIST_USERS` -- List users with filtering by department, role, location, entity\n- `RAMP_GET_MY_TRANSACTIONS` -- Get transactions for the authenticated user\n\n**Key Parameters for `RAMP_LIST_USERS`:**\n- `department_id` -- Filter by department UUID\n- `role` -- Filter by user role\n- `email` -- Filter by email address\n- `employee_id` -- Filter by employee ID\n- `entity_id` -- Filter by business entity UUID\n- `location_id` -- Filter by location UUID\n- `page_size` -- Results per page (2--100, default: 20)\n\n**Example:**\n```\nTool: RAMP_LIST_USERS\nArguments:\n  role: \"ADMIN\"\n  page_size: 50\n```\n\n---\n\n### 6. View Card Details and Accounting Fields\n\nRetrieve card information and custom accounting field configurations.\n\n**Tools:**\n- `RAMP_GET_CARD` -- Get detailed card information (spending limits, cardholder, fulfillment status)\n- `RAMP_FETCH_CUSTOM_ACCOUNTING_FIELD` -- Fetch custom accounting field definitions\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Pagination required** | All list endpoints return paginated results. Use the `start` parameter with the ID of the last entity from the previous page to iterate. |\n| **Date format** | All date parameters must be ISO 8601 datetime format (e.g., `\"2026-02-11T00:00:00Z\"`). Plain date strings will fail. |\n| **sync_status priority** | When `sync_status` is set, it supersedes both `has_no_sync_commits` and `sync_ready` parameters. |\n| **Amount filters in USD** | `min_amount` and `max_amount` are in USD. Ensure correct currency context when filtering. |\n| **state=ALL for declined** | By default, declined transactions are excluded. Set `state: \"ALL\"` to include them in results. |\n| **page_size bounds** | Must be between 2 and 100. Default is 20. Values outside this range cause errors. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `RAMP_GET_ALL_TRANSACTIONS` | List all transactions with filtering |\n| `RAMP_SEARCH_TRANSACTIONS` | Search transactions by text query |\n| `RAMP_GET_TRANSACTION` | Get details of a specific transaction |\n| `RAMP_GET_MY_TRANSACTIONS` | Get authenticated user's transactions |\n| `RAMP_LIST_REIMBURSEMENTS` | List reimbursements with filtering |\n| `RAMP_GET_REIMBURSEMENT` | Get details of a specific reimbursement |\n| `RAMP_LIST_USERS` | List organization users |\n| `RAMP_GET_CARD` | Get card details |\n| `RAMP_FETCH_CUSTOM_ACCOUNTING_FIELD` | Fetch custom accounting field config |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ravenseotools-automation/SKILL.md",
    "content": "---\nname: ravenseotools-automation\ndescription: \"Automate Ravenseotools tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ravenseotools Automation via Rube MCP\n\nAutomate Ravenseotools operations through Composio's Ravenseotools toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ravenseotools](https://composio.dev/toolkits/ravenseotools)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ravenseotools connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ravenseotools`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ravenseotools`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ravenseotools operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ravenseotools task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ravenseotools\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ravenseotools-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ravenseotools` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/re-amaze-automation/SKILL.md",
    "content": "---\nname: re-amaze-automation\ndescription: \"Automate Re Amaze tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Re Amaze Automation via Rube MCP\n\nAutomate Re Amaze operations through Composio's Re Amaze toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/re_amaze](https://composio.dev/toolkits/re_amaze)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Re Amaze connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `re_amaze`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `re_amaze`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Re Amaze operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Re Amaze task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"re_amaze\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Re Amaze-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `re_amaze` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/realphonevalidation-automation/SKILL.md",
    "content": "---\nname: realphonevalidation-automation\ndescription: \"Automate Realphonevalidation tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Realphonevalidation Automation via Rube MCP\n\nAutomate Realphonevalidation operations through Composio's Realphonevalidation toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/realphonevalidation](https://composio.dev/toolkits/realphonevalidation)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Realphonevalidation connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `realphonevalidation`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `realphonevalidation`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Realphonevalidation operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Realphonevalidation task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"realphonevalidation\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Realphonevalidation-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `realphonevalidation` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/recallai-automation/SKILL.md",
    "content": "---\nname: recallai-automation\ndescription: \"Automate Recallai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Recallai Automation via Rube MCP\n\nAutomate Recallai operations through Composio's Recallai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/recallai](https://composio.dev/toolkits/recallai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Recallai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `recallai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `recallai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Recallai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Recallai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"recallai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Recallai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `recallai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/recruitee-automation/SKILL.md",
    "content": "---\nname: recruitee-automation\ndescription: \"Automate Recruitee tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Recruitee Automation via Rube MCP\n\nAutomate Recruitee operations through Composio's Recruitee toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/recruitee](https://composio.dev/toolkits/recruitee)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Recruitee connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `recruitee`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `recruitee`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Recruitee operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Recruitee task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"recruitee\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Recruitee-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `recruitee` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/refiner-automation/SKILL.md",
    "content": "---\nname: refiner-automation\ndescription: \"Automate Refiner tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Refiner Automation via Rube MCP\n\nAutomate Refiner operations through Composio's Refiner toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/refiner](https://composio.dev/toolkits/refiner)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Refiner connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `refiner`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `refiner`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Refiner operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Refiner task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"refiner\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Refiner-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `refiner` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/remarkety-automation/SKILL.md",
    "content": "---\nname: remarkety-automation\ndescription: \"Automate Remarkety tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Remarkety Automation via Rube MCP\n\nAutomate Remarkety operations through Composio's Remarkety toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/remarkety](https://composio.dev/toolkits/remarkety)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Remarkety connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `remarkety`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `remarkety`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Remarkety operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Remarkety task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"remarkety\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Remarkety-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `remarkety` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/remote-retrieval-automation/SKILL.md",
    "content": "---\nname: remote-retrieval-automation\ndescription: \"Automate Remote Retrieval tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Remote Retrieval Automation via Rube MCP\n\nAutomate Remote Retrieval operations through Composio's Remote Retrieval toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/remote_retrieval](https://composio.dev/toolkits/remote_retrieval)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Remote Retrieval connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `remote_retrieval`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `remote_retrieval`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Remote Retrieval operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Remote Retrieval task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"remote_retrieval\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Remote Retrieval-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `remote_retrieval` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/remove-bg-automation/SKILL.md",
    "content": "---\nname: remove-bg-automation\ndescription: \"Automate Remove Bg tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Remove Bg Automation via Rube MCP\n\nAutomate Remove Bg operations through Composio's Remove Bg toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/remove_bg](https://composio.dev/toolkits/remove_bg)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Remove Bg connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `remove_bg`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `remove_bg`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Remove Bg operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Remove Bg task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"remove_bg\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Remove Bg-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `remove_bg` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/renderform-automation/SKILL.md",
    "content": "---\nname: renderform-automation\ndescription: \"Automate Renderform tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Renderform Automation via Rube MCP\n\nAutomate Renderform operations through Composio's Renderform toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/renderform](https://composio.dev/toolkits/renderform)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Renderform connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `renderform`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `renderform`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Renderform operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Renderform task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"renderform\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Renderform-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `renderform` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/repairshopr-automation/SKILL.md",
    "content": "---\nname: repairshopr-automation\ndescription: \"Automate Repairshopr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Repairshopr Automation via Rube MCP\n\nAutomate Repairshopr operations through Composio's Repairshopr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/repairshopr](https://composio.dev/toolkits/repairshopr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Repairshopr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `repairshopr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `repairshopr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Repairshopr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Repairshopr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"repairshopr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Repairshopr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `repairshopr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/replicate-automation/SKILL.md",
    "content": "---\nname: Replicate Automation\ndescription: \"Automate Replicate AI model operations -- run predictions, upload files, inspect model schemas, list versions, and manage prediction history via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Replicate Automation\n\nAutomate your Replicate AI model workflows -- run predictions on any public model (image generation, LLMs, audio, video), upload input files, inspect model schemas and documentation, list model versions, and track prediction history.\n\n**Toolkit docs:** [composio.dev/toolkits/replicate](https://composio.dev/toolkits/replicate)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Replicate account when prompted (API token authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. Get Model Details and Schema\n\nUse `REPLICATE_MODELS_GET` to inspect a model's input/output schema before running predictions.\n\n```\nTool: REPLICATE_MODELS_GET\nInputs:\n  - model_owner: string (required) -- e.g., \"meta\", \"black-forest-labs\", \"stability-ai\"\n  - model_name: string (required) -- e.g., \"meta-llama-3-8b-instruct\", \"flux-1.1-pro\"\n```\n\n**Important:** Each model has unique input keys and types. Always check the `openapi_schema` from this response before constructing prediction inputs.\n\n### 2. Run a Prediction\n\nUse `REPLICATE_MODELS_PREDICTIONS_CREATE` to run inference on any model with optional synchronous waiting and webhooks.\n\n```\nTool: REPLICATE_MODELS_PREDICTIONS_CREATE\nInputs:\n  - model_owner: string (required) -- e.g., \"meta\", \"black-forest-labs\"\n  - model_name: string (required) -- e.g., \"flux-1.1-pro\", \"sdxl\"\n  - input: object (required) -- model-specific inputs, e.g., { \"prompt\": \"A sunset over mountains\" }\n  - wait_for: integer (1-60 seconds, optional) -- synchronous wait for completion\n  - cancel_after: string (optional) -- max execution time, e.g., \"300s\", \"5m\"\n  - webhook: string (optional) -- HTTPS URL for async completion notifications\n  - webhook_events_filter: array (optional) -- [\"start\", \"output\", \"logs\", \"completed\"]\n```\n\n**Sync vs Async:** Use `wait_for` (1-60s) for fast models. For long-running jobs, omit it and use webhooks or poll via `REPLICATE_PREDICTIONS_LIST`.\n\n### 3. Upload Files for Model Input\n\nUse `REPLICATE_CREATE_FILE` to upload images, documents, or other binary inputs that models need.\n\n```\nTool: REPLICATE_CREATE_FILE\nInputs:\n  - content: string (required) -- base64-encoded file content\n  - filename: string (required) -- e.g., \"input.png\", \"audio.wav\" (max 255 bytes UTF-8)\n  - content_type: string (default \"application/octet-stream\") -- MIME type\n  - metadata: object (optional) -- custom JSON metadata\n```\n\n### 4. Read Model Documentation\n\nUse `REPLICATE_MODELS_README_GET` to access a model's README in Markdown format for detailed usage instructions.\n\n```\nTool: REPLICATE_MODELS_README_GET\nInputs:\n  - model_owner: string (required)\n  - model_name: string (required)\n```\n\n### 5. List Model Versions\n\nUse `REPLICATE_MODELS_VERSIONS_LIST` to see all available versions of a model, sorted newest first.\n\n```\nTool: REPLICATE_MODELS_VERSIONS_LIST\nInputs:\n  - model_owner: string (required)\n  - model_name: string (required)\n```\n\n### 6. Track Prediction History and Files\n\nUse `REPLICATE_PREDICTIONS_LIST` to retrieve prediction history, and `REPLICATE_FILES_GET`/`REPLICATE_FILES_LIST` to manage uploaded files.\n\n```\nTool: REPLICATE_PREDICTIONS_LIST\n  - Lists all predictions for the authenticated user with pagination\n\nTool: REPLICATE_FILES_LIST\n  - Lists uploaded files, most recent first\n\nTool: REPLICATE_FILES_GET\n  - Get details of a specific file by ID\n```\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Model-specific input keys | Each model has unique input keys and types. Using the wrong key causes validation errors. Always call `REPLICATE_MODELS_GET` first to check the `openapi_schema`. |\n| File upload encoding | `REPLICATE_CREATE_FILE` requires base64-encoded content. Binary files treated as text (UTF-8) will fail with decode errors. |\n| Public vs deployment paths | Public models must be run via `REPLICATE_MODELS_PREDICTIONS_CREATE`. Using deployment-oriented paths causes HTTP 404 failures. |\n| Sync wait limits | `wait_for` supports 1-60 seconds only. Long-running jobs need async handling via webhooks or polling `REPLICATE_PREDICTIONS_LIST`. |\n| Image model constraints | Image models like flux-1.1-pro have specific constraints (e.g., max width/height 1440px, valid aspect ratios). Check the model schema first. |\n| Stale file references | Heavy usage creates many uploads. Routinely check `REPLICATE_FILES_LIST` to avoid using stale `file_id` references. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `REPLICATE_MODELS_GET` | Get model details, schema, and metadata |\n| `REPLICATE_MODELS_PREDICTIONS_CREATE` | Run a prediction on a model |\n| `REPLICATE_CREATE_FILE` | Upload a file for model input |\n| `REPLICATE_MODELS_README_GET` | Get model README documentation |\n| `REPLICATE_MODELS_VERSIONS_LIST` | List all versions of a model |\n| `REPLICATE_PREDICTIONS_LIST` | List prediction history with pagination |\n| `REPLICATE_FILES_LIST` | List uploaded files |\n| `REPLICATE_FILES_GET` | Get file details by ID |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/reply-automation/SKILL.md",
    "content": "---\nname: reply-automation\ndescription: \"Automate Reply tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Reply Automation via Rube MCP\n\nAutomate Reply operations through Composio's Reply toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/reply](https://composio.dev/toolkits/reply)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Reply connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `reply`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `reply`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Reply operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Reply task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"reply\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Reply-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `reply` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/reply-io-automation/SKILL.md",
    "content": "---\nname: reply-io-automation\ndescription: \"Automate Reply IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Reply IO Automation via Rube MCP\n\nAutomate Reply IO operations through Composio's Reply IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/reply_io](https://composio.dev/toolkits/reply_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Reply IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `reply_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `reply_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Reply IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Reply IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"reply_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Reply IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `reply_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/resend-automation/SKILL.md",
    "content": "---\nname: resend-automation\ndescription: \"Automate Resend tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Resend Automation via Rube MCP\n\nAutomate Resend operations through Composio's Resend toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/resend](https://composio.dev/toolkits/resend)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Resend connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `resend`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `resend`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Resend operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Resend task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"resend\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Resend-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `resend` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/respond-io-automation/SKILL.md",
    "content": "---\nname: respond-io-automation\ndescription: \"Automate Respond IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Respond IO Automation via Rube MCP\n\nAutomate Respond IO operations through Composio's Respond IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/respond_io](https://composio.dev/toolkits/respond_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Respond IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `respond_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `respond_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Respond IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Respond IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"respond_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Respond IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `respond_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/retailed-automation/SKILL.md",
    "content": "---\nname: retailed-automation\ndescription: \"Automate Retailed tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Retailed Automation via Rube MCP\n\nAutomate Retailed operations through Composio's Retailed toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/retailed](https://composio.dev/toolkits/retailed)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Retailed connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `retailed`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `retailed`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Retailed operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Retailed task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"retailed\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Retailed-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `retailed` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/retellai-automation/SKILL.md",
    "content": "---\nname: retellai-automation\ndescription: \"Automate Retellai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Retellai Automation via Rube MCP\n\nAutomate Retellai operations through Composio's Retellai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/retellai](https://composio.dev/toolkits/retellai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Retellai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `retellai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `retellai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Retellai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Retellai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"retellai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Retellai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `retellai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/retently-automation/SKILL.md",
    "content": "---\nname: retently-automation\ndescription: \"Automate Retently tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Retently Automation via Rube MCP\n\nAutomate Retently operations through Composio's Retently toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/retently](https://composio.dev/toolkits/retently)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Retently connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `retently`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `retently`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Retently operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Retently task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"retently\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Retently-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `retently` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rev-ai-automation/SKILL.md",
    "content": "---\nname: rev-ai-automation\ndescription: \"Automate Rev AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rev AI Automation via Rube MCP\n\nAutomate Rev AI operations through Composio's Rev AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rev_ai](https://composio.dev/toolkits/rev_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rev AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rev_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rev_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rev AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rev AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rev_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rev AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rev_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/revolt-automation/SKILL.md",
    "content": "---\nname: revolt-automation\ndescription: \"Automate Revolt tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Revolt Automation via Rube MCP\n\nAutomate Revolt operations through Composio's Revolt toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/revolt](https://composio.dev/toolkits/revolt)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Revolt connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `revolt`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `revolt`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Revolt operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Revolt task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"revolt\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Revolt-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `revolt` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ring-central-automation/SKILL.md",
    "content": "---\nname: RingCentral Automation\ndescription: \"RingCentral automation via Rube MCP -- toolkit not currently available in Composio; no RING_CENTRAL_ tools found\"\nrequires:\n  mcp:\n    - rube\n---\n\n# RingCentral Automation\n\n> **Status: Toolkit Not Available** -- RUBE_SEARCH_TOOLS returned no `ring_central`-specific tools. The RingCentral toolkit is not currently available in Composio's tool catalog. Searches returned tools from unrelated toolkits (ClickSend, Telnyx, Slack) instead.\n\n**Toolkit docs:** [composio.dev/toolkits/ring_central](https://composio.dev/toolkits/ring_central)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Check availability by calling `RUBE_SEARCH_TOOLS` with RingCentral-related queries\n3. If `RING_CENTRAL_*` tools appear in the future, connect via `RUBE_MANAGE_CONNECTIONS` with toolkit `ring_central`\n\n---\n\n## Current Status\n\nAs of the last tool discovery scan, no `RING_CENTRAL_*` tool slugs were returned by RUBE_SEARCH_TOOLS. Queries for RingCentral messaging, call logs, fax, and extension management all returned tools from other toolkits:\n\n- SMS/messaging queries returned **ClickSend** tools (`CLICKSEND_CREATE_SMS_SEND`, etc.)\n- Call management queries returned **Pipedrive** call log tools\n- Telephony/VoIP queries returned **Telnyx** notification tools\n- Fax queries returned **ClickSend** fax automation tools\n\nThis indicates the `ring_central` toolkit either has no tools registered or is not yet integrated into the Composio platform.\n\n---\n\n## Alternatives\n\nIf you need telephony, SMS, or communication automation, consider these available toolkits:\n\n| Need | Alternative Toolkit | Example Tool |\n|------|-------------------|--------------|\n| SMS messaging | ClickSend | `CLICKSEND_CREATE_SMS_SEND` |\n| VoIP/telephony | Telnyx | `TELNYX_CREATE_NOTIFICATION_CHANNEL` |\n| Team messaging | Slack / Webex | `SLACK_SEND_MESSAGE` / `WEBEX_MESSAGING_CREATE_MESSAGE` |\n\n---\n\n## When Tools Become Available\n\nOnce RingCentral tools are added to Composio, this skill should be updated with real tool slugs, schemas, and pitfalls following the same pattern as other automation skills in this collection.\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ring_central-automation/SKILL.md",
    "content": "---\nname: ring_central-automation\ndescription: \"Automate RingCentral tasks via Rube MCP (Composio): calls, messages, meetings, and unified communications. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# RingCentral Automation via Rube MCP\n\nAutomate RingCentral operations through Composio's RingCentral toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ring_central](https://composio.dev/toolkits/ring_central)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active RingCentral connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ring_central`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ring_central`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"calls, messages, meetings, and unified communications\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for RingCentral\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available RingCentral Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available RingCentral tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute RingCentral Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple RingCentral operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the RingCentral connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with RingCentral-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ring_central` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/ring_central](https://composio.dev/toolkits/ring_central)\n"
  },
  {
    "path": "composio-skills/rippling-automation/SKILL.md",
    "content": "---\nname: rippling-automation\ndescription: \"Automate Rippling tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rippling Automation via Rube MCP\n\nAutomate Rippling operations through Composio's Rippling toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rippling](https://composio.dev/toolkits/rippling)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rippling connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rippling`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rippling`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rippling operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rippling task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rippling\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rippling-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rippling` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ritekit-automation/SKILL.md",
    "content": "---\nname: ritekit-automation\ndescription: \"Automate Ritekit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ritekit Automation via Rube MCP\n\nAutomate Ritekit operations through Composio's Ritekit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ritekit](https://composio.dev/toolkits/ritekit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ritekit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ritekit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ritekit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ritekit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ritekit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ritekit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ritekit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ritekit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rkvst-automation/SKILL.md",
    "content": "---\nname: rkvst-automation\ndescription: \"Automate Rkvst tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rkvst Automation via Rube MCP\n\nAutomate Rkvst operations through Composio's Rkvst toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rkvst](https://composio.dev/toolkits/rkvst)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rkvst connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rkvst`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rkvst`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rkvst operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rkvst task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rkvst\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rkvst-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rkvst` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rocketlane-automation/SKILL.md",
    "content": "---\nname: rocketlane-automation\ndescription: \"Automate Rocketlane tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rocketlane Automation via Rube MCP\n\nAutomate Rocketlane operations through Composio's Rocketlane toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rocketlane](https://composio.dev/toolkits/rocketlane)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rocketlane connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rocketlane`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rocketlane`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rocketlane operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rocketlane task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rocketlane\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rocketlane-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rocketlane` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rootly-automation/SKILL.md",
    "content": "---\nname: rootly-automation\ndescription: \"Automate Rootly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rootly Automation via Rube MCP\n\nAutomate Rootly operations through Composio's Rootly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rootly](https://composio.dev/toolkits/rootly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rootly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rootly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rootly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rootly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rootly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rootly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rootly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rootly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/rosette-text-analytics-automation/SKILL.md",
    "content": "---\nname: rosette-text-analytics-automation\ndescription: \"Automate Rosette Text Analytics tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Rosette Text Analytics Automation via Rube MCP\n\nAutomate Rosette Text Analytics operations through Composio's Rosette Text Analytics toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/rosette_text_analytics](https://composio.dev/toolkits/rosette_text_analytics)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Rosette Text Analytics connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `rosette_text_analytics`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `rosette_text_analytics`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Rosette Text Analytics operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Rosette Text Analytics task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"rosette_text_analytics\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Rosette Text Analytics-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `rosette_text_analytics` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/route4me-automation/SKILL.md",
    "content": "---\nname: route4me-automation\ndescription: \"Automate Route4me tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Route4me Automation via Rube MCP\n\nAutomate Route4me operations through Composio's Route4me toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/route4me](https://composio.dev/toolkits/route4me)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Route4me connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `route4me`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `route4me`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Route4me operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Route4me task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"route4me\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Route4me-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `route4me` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/safetyculture-automation/SKILL.md",
    "content": "---\nname: safetyculture-automation\ndescription: \"Automate Safetyculture tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Safetyculture Automation via Rube MCP\n\nAutomate Safetyculture operations through Composio's Safetyculture toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/safetyculture](https://composio.dev/toolkits/safetyculture)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Safetyculture connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `safetyculture`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `safetyculture`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Safetyculture operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Safetyculture task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"safetyculture\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Safetyculture-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `safetyculture` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sage-automation/SKILL.md",
    "content": "---\nname: sage-automation\ndescription: \"Automate Sage tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sage Automation via Rube MCP\n\nAutomate Sage operations through Composio's Sage toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sage](https://composio.dev/toolkits/sage)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sage connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sage`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sage`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sage operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sage task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sage\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sage-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sage` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/salesforce-marketing-cloud-automation/SKILL.md",
    "content": "---\nname: salesforce-marketing-cloud-automation\ndescription: \"Automate Salesforce Marketing Cloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Salesforce Marketing Cloud Automation via Rube MCP\n\nAutomate Salesforce Marketing Cloud operations through Composio's Salesforce Marketing Cloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/salesforce_marketing_cloud](https://composio.dev/toolkits/salesforce_marketing_cloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Salesforce Marketing Cloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_marketing_cloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_marketing_cloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Salesforce Marketing Cloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Salesforce Marketing Cloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"salesforce_marketing_cloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Salesforce Marketing Cloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_marketing_cloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/salesforce-service-cloud-automation/SKILL.md",
    "content": "---\nname: salesforce-service-cloud-automation\ndescription: \"Automate Salesforce Service Cloud tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Salesforce Service Cloud Automation via Rube MCP\n\nAutomate Salesforce Service Cloud operations through Composio's Salesforce Service Cloud toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/salesforce_service_cloud](https://composio.dev/toolkits/salesforce_service_cloud)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Salesforce Service Cloud connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_service_cloud`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_service_cloud`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Salesforce Service Cloud operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Salesforce Service Cloud task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"salesforce_service_cloud\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Salesforce Service Cloud-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `salesforce_service_cloud` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/salesmate-automation/SKILL.md",
    "content": "---\nname: salesmate-automation\ndescription: \"Automate Salesmate tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Salesmate Automation via Rube MCP\n\nAutomate Salesmate operations through Composio's Salesmate toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/salesmate](https://composio.dev/toolkits/salesmate)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Salesmate connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `salesmate`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `salesmate`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Salesmate operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Salesmate task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"salesmate\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Salesmate-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `salesmate` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sap-successfactors-automation/SKILL.md",
    "content": "---\nname: sap-successfactors-automation\ndescription: \"Automate SAP SuccessFactors tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SAP SuccessFactors Automation via Rube MCP\n\nAutomate SAP SuccessFactors operations through Composio's SAP SuccessFactors toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sap_successfactors](https://composio.dev/toolkits/sap_successfactors)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SAP SuccessFactors connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sap_successfactors`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sap_successfactors`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"SAP SuccessFactors operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific SAP SuccessFactors task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sap_successfactors\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SAP SuccessFactors-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sap_successfactors` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/satismeter-automation/SKILL.md",
    "content": "---\nname: satismeter-automation\ndescription: \"Automate Satismeter tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Satismeter Automation via Rube MCP\n\nAutomate Satismeter operations through Composio's Satismeter toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/satismeter](https://composio.dev/toolkits/satismeter)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Satismeter connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `satismeter`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `satismeter`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Satismeter operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Satismeter task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"satismeter\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Satismeter-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `satismeter` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/scrape-do-automation/SKILL.md",
    "content": "---\nname: scrape-do-automation\ndescription: \"Automate Scrape Do tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Scrape Do Automation via Rube MCP\n\nAutomate Scrape Do operations through Composio's Scrape Do toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/scrape_do](https://composio.dev/toolkits/scrape_do)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Scrape Do connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `scrape_do`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `scrape_do`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Scrape Do operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Scrape Do task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"scrape_do\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Scrape Do-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `scrape_do` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/scrapegraph-ai-automation/SKILL.md",
    "content": "---\nname: scrapegraph-ai-automation\ndescription: \"Automate Scrapegraph AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Scrapegraph AI Automation via Rube MCP\n\nAutomate Scrapegraph AI operations through Composio's Scrapegraph AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/scrapegraph_ai](https://composio.dev/toolkits/scrapegraph_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Scrapegraph AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapegraph_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapegraph_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Scrapegraph AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Scrapegraph AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"scrapegraph_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Scrapegraph AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapegraph_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/scrapfly-automation/SKILL.md",
    "content": "---\nname: scrapfly-automation\ndescription: \"Automate Scrapfly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Scrapfly Automation via Rube MCP\n\nAutomate Scrapfly operations through Composio's Scrapfly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/scrapfly](https://composio.dev/toolkits/scrapfly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Scrapfly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapfly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapfly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Scrapfly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Scrapfly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"scrapfly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Scrapfly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapfly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/scrapingant-automation/SKILL.md",
    "content": "---\nname: scrapingant-automation\ndescription: \"Automate Scrapingant tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Scrapingant Automation via Rube MCP\n\nAutomate Scrapingant operations through Composio's Scrapingant toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/scrapingant](https://composio.dev/toolkits/scrapingant)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Scrapingant connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingant`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingant`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Scrapingant operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Scrapingant task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"scrapingant\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Scrapingant-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingant` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/scrapingbee-automation/SKILL.md",
    "content": "---\nname: scrapingbee-automation\ndescription: \"Automate Scrapingbee tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Scrapingbee Automation via Rube MCP\n\nAutomate Scrapingbee operations through Composio's Scrapingbee toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/scrapingbee](https://composio.dev/toolkits/scrapingbee)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Scrapingbee connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingbee`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingbee`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Scrapingbee operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Scrapingbee task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"scrapingbee\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Scrapingbee-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `scrapingbee` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/screenshot-fyi-automation/SKILL.md",
    "content": "---\nname: screenshot-fyi-automation\ndescription: \"Automate Screenshot Fyi tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Screenshot Fyi Automation via Rube MCP\n\nAutomate Screenshot Fyi operations through Composio's Screenshot Fyi toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/screenshot_fyi](https://composio.dev/toolkits/screenshot_fyi)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Screenshot Fyi connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshot_fyi`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshot_fyi`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Screenshot Fyi operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Screenshot Fyi task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"screenshot_fyi\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Screenshot Fyi-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshot_fyi` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/screenshotone-automation/SKILL.md",
    "content": "---\nname: screenshotone-automation\ndescription: \"Automate Screenshotone tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Screenshotone Automation via Rube MCP\n\nAutomate Screenshotone operations through Composio's Screenshotone toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/screenshotone](https://composio.dev/toolkits/screenshotone)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Screenshotone connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshotone`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshotone`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Screenshotone operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Screenshotone task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"screenshotone\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Screenshotone-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `screenshotone` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/seat-geek-automation/SKILL.md",
    "content": "---\nname: seat-geek-automation\ndescription: \"Automate Seat Geek tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Seat Geek Automation via Rube MCP\n\nAutomate Seat Geek operations through Composio's Seat Geek toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/seat_geek](https://composio.dev/toolkits/seat_geek)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Seat Geek connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `seat_geek`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `seat_geek`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Seat Geek operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Seat Geek task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"seat_geek\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Seat Geek-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `seat_geek` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/securitytrails-automation/SKILL.md",
    "content": "---\nname: securitytrails-automation\ndescription: \"Automate Securitytrails tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Securitytrails Automation via Rube MCP\n\nAutomate Securitytrails operations through Composio's Securitytrails toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/securitytrails](https://composio.dev/toolkits/securitytrails)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Securitytrails connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `securitytrails`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `securitytrails`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Securitytrails operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Securitytrails task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"securitytrails\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Securitytrails-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `securitytrails` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/segmetrics-automation/SKILL.md",
    "content": "---\nname: segmetrics-automation\ndescription: \"Automate Segmetrics tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Segmetrics Automation via Rube MCP\n\nAutomate Segmetrics operations through Composio's Segmetrics toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/segmetrics](https://composio.dev/toolkits/segmetrics)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Segmetrics connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `segmetrics`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `segmetrics`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Segmetrics operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Segmetrics task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"segmetrics\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Segmetrics-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `segmetrics` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/seismic-automation/SKILL.md",
    "content": "---\nname: seismic-automation\ndescription: \"Automate Seismic tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Seismic Automation via Rube MCP\n\nAutomate Seismic operations through Composio's Seismic toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/seismic](https://composio.dev/toolkits/seismic)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Seismic connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `seismic`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `seismic`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Seismic operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Seismic task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"seismic\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Seismic-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `seismic` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/semanticscholar-automation/SKILL.md",
    "content": "---\nname: semanticscholar-automation\ndescription: \"Automate Semanticscholar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Semanticscholar Automation via Rube MCP\n\nAutomate Semanticscholar operations through Composio's Semanticscholar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/semanticscholar](https://composio.dev/toolkits/semanticscholar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Semanticscholar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `semanticscholar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `semanticscholar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Semanticscholar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Semanticscholar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"semanticscholar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Semanticscholar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `semanticscholar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/semrush-automation/SKILL.md",
    "content": "---\nname: SEMrush Automation\ndescription: \"Automate SEO analysis with SEMrush -- research keywords, analyze domain organic rankings, audit backlinks, assess keyword difficulty, and discover related terms through the Composio SEMrush integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# SEMrush Automation\n\nRun **SEMrush** SEO analytics directly from Claude Code. Analyze domain keywords, audit backlink profiles, research keyword difficulty, discover related terms, and track organic page performance without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/semrush](https://composio.dev/toolkits/semrush)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Connect your SEMrush account when prompted. The agent will provide an authentication link.\n3. All SEMrush tools require a `database` parameter specifying the regional database (e.g., `us`, `uk`, `de`). Choose the correct region for your target audience.\n\n---\n\n## Core Workflows\n\n### 1. Domain Organic Keywords Analysis\n\nRetrieve all organic search keywords for a domain, including positions, traffic estimates, CPC, and keyword difficulty.\n\n**Tool:** `SEMRUSH_DOMAIN_ORGANIC_SEARCH_KEYWORDS`\n\nKey parameters:\n- `domain` (required) -- e.g., `example.com`\n- `database` (required) -- regional database code (e.g., `us`, `uk`, `de`)\n- `display_limit` (default 10000) and `display_offset` (default 0) -- pagination\n- `display_sort` -- sort by position, traffic, volume, etc. (e.g., `tr_desc` for traffic descending)\n- `display_date` -- historical data in `YYYYMM15` format (monthly) or `YYYYMMDD` (daily)\n- `export_columns` -- specify columns like `Ph` (phrase), `Po` (position), `Nq` (volume), `Tr` (traffic), `Kd` (difficulty)\n- `display_filter` -- filter by specific columns\n\nExample prompt: *\"Get the top 100 organic keywords for example.com in the US database, sorted by traffic\"*\n\n---\n\n### 2. Keyword Overview and Batch Analysis\n\nGet detailed metrics for individual keywords or analyze up to 100 keywords at once.\n\n**Tools:** `SEMRUSH_KEYWORD_OVERVIEW_ONE_DATABASE`, `SEMRUSH_BATCH_KEYWORD_OVERVIEW`\n\nFor single keyword:\n- `phrase` (required) -- keyword to investigate\n- `database` (required) -- regional database\n\nFor batch (up to 100 keywords):\n- `phrase` (required) -- semicolon-separated keywords (max 255 chars total)\n- `database` (required) -- regional database\n- `export_columns` -- `Ph` (phrase), `Nq` (volume), `Cp` (CPC), `Co` (competition), `Kd` (difficulty), `In` (intent)\n\nExample prompt: *\"Get keyword metrics for 'seo services;content marketing;link building' in the US database\"*\n\n---\n\n### 3. Domain Organic Pages Report\n\nDiscover which URLs on a domain drive the most organic traffic and visibility.\n\n**Tool:** `SEMRUSH_DOMAIN_ORGANIC_PAGES`\n\nKey parameters:\n- `domain` (required) -- target domain\n- `database` (required) -- regional database\n- `display_sort` -- e.g., `pc_desc` for traffic share descending\n- `display_limit` and `display_offset` -- pagination\n- `export_columns` -- `Ur` (URL), `Pc` (traffic %), `Tg` (traffic), `Tr` (traffic cost)\n\nExample prompt: *\"Show the top 50 organic pages for example.com ranked by traffic share\"*\n\n---\n\n### 4. Backlink Profile Overview\n\nGet a summary of backlinks for a domain including Authority Score, link types, and referring domain counts.\n\n**Tool:** `SEMRUSH_BACKLINKS_OVERVIEW`\n\nKey parameters:\n- `target` (required) -- domain, subdomain, or full URL\n- `target_type` (required) -- `root_domain`, `domain`, or `url`\n- `export_columns` -- `ascore` (Authority Score), `total` (total backlinks), `domains_num` (referring domains), `follows_num`, `nofollows_num`, etc.\n\nExample prompt: *\"Get the backlink overview for example.com including Authority Score and referring domain count\"*\n\n---\n\n### 5. Keyword Difficulty Assessment\n\nScore how hard it is to rank in the top 10 for specific keywords (0-100 scale).\n\n**Tool:** `SEMRUSH_KEYWORD_DIFFICULTY`\n\nKey parameters:\n- `phrase` (required) -- keyword to analyze\n- `database` (required) -- regional database\n- `export_columns` -- `Ph` (phrase), `Kd` (difficulty score)\n\nExample prompt: *\"What is the keyword difficulty for 'best project management software' in the US?\"*\n\n---\n\n### 6. Discover Related Keywords\n\nFind synonyms, variations, and related terms for a seed keyword to expand your content strategy.\n\n**Tool:** `SEMRUSH_RELATED_KEYWORDS`\n\nKey parameters:\n- `phrase` (required) -- seed keyword\n- `database` (required) -- regional database\n- `display_limit` (default 10000) -- max results\n- `display_sort` -- e.g., `nq_desc` for volume descending, `kd_asc` for easiest first\n- `export_columns` -- `Ph`, `Nq`, `Kd`, `Cp`, `Co`, `Rr` (relatedness score)\n\nExample prompt: *\"Find related keywords for 'project management' in the US, sorted by search volume\"*\n\n---\n\n## Known Pitfalls\n\n- **Pagination is essential:** `SEMRUSH_DOMAIN_ORGANIC_SEARCH_KEYWORDS` and `SEMRUSH_DOMAIN_ORGANIC_PAGES` can return very large datasets. Always use `display_limit` and `display_offset` instead of assuming a single page is complete.\n- **CSV-style responses:** Many SEMrush tools return data as CSV-style text in a single field (e.g., `data/keyword_data`). You must parse rows and columns before analysis or joining reports.\n- **\"ERROR 50 :: NOTHING FOUND\":** This literal string means the domain or keyword has no data in that database. Treat it as a valid zero-result response, not a transport error.\n- **Batch keyword limits:** `SEMRUSH_BATCH_KEYWORD_OVERVIEW` may return HTTP 400 for problematic or oversized batches (max 255 chars total for the `phrase` field). Shrink batches or fall back to `SEMRUSH_KEYWORD_OVERVIEW_ONE_DATABASE` for individual lookups.\n- **Date format:** Historical dates must use `YYYYMM15` format for monthly data (e.g., `20231015`). Using an incorrect format will return unexpected results.\n- **Regional database matters:** Always use the correct regional database for your target audience. Results for `us` vs `uk` can differ dramatically in volume, CPC, and rankings.\n- **Column codes:** Export columns use short codes (`Ph`, `Nq`, `Kd`, etc.). Avoid over-narrowing `export_columns` so key metrics like traffic, CPC, position, and difficulty are retained.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `SEMRUSH_DOMAIN_ORGANIC_SEARCH_KEYWORDS` | Organic keywords for a domain with positions and traffic |\n| `SEMRUSH_KEYWORD_OVERVIEW_ONE_DATABASE` | Single keyword metrics (volume, CPC, difficulty) |\n| `SEMRUSH_BATCH_KEYWORD_OVERVIEW` | Batch metrics for up to 100 keywords |\n| `SEMRUSH_DOMAIN_ORGANIC_PAGES` | Top organic pages for a domain by traffic |\n| `SEMRUSH_BACKLINKS_OVERVIEW` | Backlink profile summary with Authority Score |\n| `SEMRUSH_BACKLINKS` | Detailed backlinks list for a target |\n| `SEMRUSH_KEYWORD_DIFFICULTY` | Keyword difficulty score (0-100) |\n| `SEMRUSH_RELATED_KEYWORDS` | Related/similar keywords for a seed phrase |\n| `SEMRUSH_CATEGORIES` | Domain categories with confidence ratings |\n| `SEMRUSH_DOMAIN_ORGANIC_SUBDOMAINS` | Subdomain-level organic rankings breakdown |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendbird-ai-chabot-automation/SKILL.md",
    "content": "---\nname: sendbird-ai-chabot-automation\ndescription: \"Automate Sendbird AI Chabot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendbird AI Chabot Automation via Rube MCP\n\nAutomate Sendbird AI Chabot operations through Composio's Sendbird AI Chabot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendbird_ai_chabot](https://composio.dev/toolkits/sendbird_ai_chabot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendbird AI Chabot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird_ai_chabot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird_ai_chabot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendbird AI Chabot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendbird AI Chabot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendbird_ai_chabot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendbird AI Chabot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird_ai_chabot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendbird-automation/SKILL.md",
    "content": "---\nname: sendbird-automation\ndescription: \"Automate Sendbird tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendbird Automation via Rube MCP\n\nAutomate Sendbird operations through Composio's Sendbird toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendbird](https://composio.dev/toolkits/sendbird)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendbird connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendbird operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendbird task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendbird\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendbird-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendbird` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendfox-automation/SKILL.md",
    "content": "---\nname: sendfox-automation\ndescription: \"Automate Sendfox tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendfox Automation via Rube MCP\n\nAutomate Sendfox operations through Composio's Sendfox toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendfox](https://composio.dev/toolkits/sendfox)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendfox connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendfox`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendfox`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendfox operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendfox task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendfox\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendfox-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendfox` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendlane-automation/SKILL.md",
    "content": "---\nname: sendlane-automation\ndescription: \"Automate Sendlane tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendlane Automation via Rube MCP\n\nAutomate Sendlane operations through Composio's Sendlane toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendlane](https://composio.dev/toolkits/sendlane)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendlane connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendlane`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendlane`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendlane operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendlane task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendlane\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendlane-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendlane` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendloop-automation/SKILL.md",
    "content": "---\nname: sendloop-automation\ndescription: \"Automate Sendloop tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendloop Automation via Rube MCP\n\nAutomate Sendloop operations through Composio's Sendloop toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendloop](https://composio.dev/toolkits/sendloop)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendloop connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendloop`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendloop`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendloop operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendloop task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendloop\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendloop-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendloop` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sendspark-automation/SKILL.md",
    "content": "---\nname: sendspark-automation\ndescription: \"Automate Sendspark tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sendspark Automation via Rube MCP\n\nAutomate Sendspark operations through Composio's Sendspark toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sendspark](https://composio.dev/toolkits/sendspark)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sendspark connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sendspark`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sendspark`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sendspark operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sendspark task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sendspark\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sendspark-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sendspark` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sensibo-automation/SKILL.md",
    "content": "---\nname: sensibo-automation\ndescription: \"Automate Sensibo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sensibo Automation via Rube MCP\n\nAutomate Sensibo operations through Composio's Sensibo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sensibo](https://composio.dev/toolkits/sensibo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sensibo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sensibo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sensibo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sensibo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sensibo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sensibo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sensibo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sensibo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/seqera-automation/SKILL.md",
    "content": "---\nname: seqera-automation\ndescription: \"Automate Seqera tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Seqera Automation via Rube MCP\n\nAutomate Seqera operations through Composio's Seqera toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/seqera](https://composio.dev/toolkits/seqera)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Seqera connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `seqera`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `seqera`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Seqera operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Seqera task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"seqera\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Seqera-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `seqera` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/serpapi-automation/SKILL.md",
    "content": "---\nname: serpapi-automation\ndescription: \"Automate Serpapi tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Serpapi Automation via Rube MCP\n\nAutomate Serpapi operations through Composio's Serpapi toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/serpapi](https://composio.dev/toolkits/serpapi)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Serpapi connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `serpapi`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `serpapi`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Serpapi operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Serpapi task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"serpapi\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Serpapi-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `serpapi` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/serpdog-automation/SKILL.md",
    "content": "---\nname: serpdog-automation\ndescription: \"Automate Serpdog tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Serpdog Automation via Rube MCP\n\nAutomate Serpdog operations through Composio's Serpdog toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/serpdog](https://composio.dev/toolkits/serpdog)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Serpdog connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `serpdog`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `serpdog`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Serpdog operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Serpdog task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"serpdog\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Serpdog-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `serpdog` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/serply-automation/SKILL.md",
    "content": "---\nname: serply-automation\ndescription: \"Automate Serply tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Serply Automation via Rube MCP\n\nAutomate Serply operations through Composio's Serply toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/serply](https://composio.dev/toolkits/serply)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Serply connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `serply`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `serply`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Serply operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Serply task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"serply\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Serply-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `serply` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/servicem8-automation/SKILL.md",
    "content": "---\nname: servicem8-automation\ndescription: \"Automate Servicem8 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Servicem8 Automation via Rube MCP\n\nAutomate Servicem8 operations through Composio's Servicem8 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/servicem8](https://composio.dev/toolkits/servicem8)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Servicem8 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `servicem8`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `servicem8`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Servicem8 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Servicem8 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"servicem8\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Servicem8-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `servicem8` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sevdesk-automation/SKILL.md",
    "content": "---\nname: sevdesk-automation\ndescription: \"Automate Sevdesk tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sevdesk Automation via Rube MCP\n\nAutomate Sevdesk operations through Composio's Sevdesk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sevdesk](https://composio.dev/toolkits/sevdesk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sevdesk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sevdesk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sevdesk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sevdesk operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sevdesk task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sevdesk\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sevdesk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sevdesk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/share-point-automation/SKILL.md",
    "content": "---\nname: SharePoint Automation\ndescription: \"SharePoint Automation: manage sites, lists, documents, folders, pages, and search content across SharePoint and OneDrive\"\nrequires:\n  mcp: [rube]\n---\n\n# SharePoint Automation\n\nAutomate SharePoint operations including managing sites, lists, documents, folders, and pages. Integrates with both SharePoint REST API and Microsoft Graph via OneDrive.\n\n**Toolkit docs:** [composio.dev/toolkits/share_point](https://composio.dev/toolkits/share_point)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure active connections exist for the `share_point` and `one_drive` toolkits. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n> **Note:** Many OneDrive/SharePoint tools only work with organizational Microsoft 365 accounts (Azure AD/Entra ID). Personal Microsoft accounts are NOT supported.\n\n---\n\n## Core Workflows\n\n### 1. List and Browse Sites\n\nRetrieve site details and enumerate subsites to discover the SharePoint topology.\n\n**Tools:**\n- `ONE_DRIVE_GET_SITE_DETAILS` -- Get metadata for a specific site by ID\n- `ONE_DRIVE_LIST_SITE_SUBSITES` -- List all subsites of a parent site\n\n**Key Parameters:**\n- `site_id` (required) -- Composite format: `hostname,site-collection-guid,web-guid` (e.g., `\"contoso.sharepoint.com,da60e844-...,712a596e-...\"`)\n\n**Example:**\n```\nTool: ONE_DRIVE_GET_SITE_DETAILS\nArguments:\n  site_id: \"contoso.sharepoint.com,2C712604-1370-44E7-A1F5-426573FDA80A,2D2244C3-251A-49EA-93A8-39E1C3A060FE\"\n```\n\n---\n\n### 2. Manage Lists\n\nCreate lists, enumerate existing lists, and retrieve list items.\n\n**Tools:**\n- `SHARE_POINT_LIST_ALL_LISTS` -- Retrieve all lists on a site (supports OData filter, select, orderby, top)\n- `SHARE_POINT_SHAREPOINT_CREATE_LIST` -- Create a new list with a specified template\n- `ONE_DRIVE_LIST_SITE_LISTS` -- List all lists under a site via Microsoft Graph\n- `ONE_DRIVE_GET_SHAREPOINT_LIST_ITEMS` -- Retrieve items from a specific list\n\n**Key Parameters for `SHARE_POINT_SHAREPOINT_CREATE_LIST`:**\n- `name` (required) -- List name\n- `template` (required) -- Template type: `\"genericList\"`, `\"documentLibrary\"`, `\"tasks\"`, etc.\n- `description` -- Optional description\n\n**Key Parameters for `SHARE_POINT_LIST_ALL_LISTS`:**\n- `filter` -- OData filter, e.g., `\"Hidden eq false\"`\n- `select` -- Properties to return, e.g., `\"Title,Id\"`\n- `orderby` -- Sort expression, e.g., `\"Title desc\"`\n- `top` -- Limit results count\n\n**Example:**\n```\nTool: SHARE_POINT_SHAREPOINT_CREATE_LIST\nArguments:\n  name: \"Project Tasks\"\n  template: \"tasks\"\n  description: \"Task tracking for Q1 deliverables\"\n```\n\n---\n\n### 3. Manage Folders and Files\n\nCreate folders, list files within folders, and navigate the document library.\n\n**Tools:**\n- `SHARE_POINT_SHAREPOINT_CREATE_FOLDER` -- Create a new folder in a document library\n- `SHARE_POINT_LIST_FILES_IN_FOLDER` -- List files within a folder by server-relative URL\n- `SHARE_POINT_GET_FOLDER_BY_SERVER_RELATIVE_URL` -- Get folder metadata by path\n\n**Key Parameters for `SHARE_POINT_SHAREPOINT_CREATE_FOLDER`:**\n- `folder_name` (required) -- Name of the folder to create\n- `document_library` -- Target library (default: `\"Shared Documents\"`)\n- `relative_path` -- Additional path within the library\n\n**Key Parameters for `SHARE_POINT_LIST_FILES_IN_FOLDER`:**\n- `folder_name` (required) -- Server-relative URL, e.g., `\"/Shared Documents\"`\n- `select` -- Comma-separated properties, e.g., `\"Name,ServerRelativeUrl,Length\"`\n- `top` -- Limit results count\n- `orderby` -- Sort expression, e.g., `\"Name desc\"`\n\n**Example:**\n```\nTool: SHARE_POINT_LIST_FILES_IN_FOLDER\nArguments:\n  folder_name: \"/Shared Documents/Reports\"\n  select: \"Name,ServerRelativeUrl,Length\"\n  top: 50\n```\n\n---\n\n### 4. Search SharePoint Content\n\nUse Keyword Query Language (KQL) to search documents, list items, and other content across the site.\n\n**Tool:** `SHARE_POINT_SEARCH_QUERY`\n\n**Key Parameters:**\n- `querytext` (required) -- KQL query, e.g., `\"project report\"`, `\"FileType:docx\"`, `\"Author:\\\"John Doe\\\"\"`\n- `rowlimit` -- Max results per request (default ~50, max 500)\n- `startrow` -- Zero-based offset for pagination\n- `selectproperties` -- Properties to return, e.g., `\"Title,Author,Path\"`\n- `refinementfilters` -- Narrow results, e.g., `\"FileType:equals(\\\"docx\\\")\"`\n\n**Example:**\n```\nTool: SHARE_POINT_SEARCH_QUERY\nArguments:\n  querytext: \"IsDocument:1 FileType:pdf\"\n  rowlimit: 25\n  selectproperties: \"Title,Author,Path,LastModifiedTime\"\n```\n\n---\n\n### 5. Track List Changes (Delta Query)\n\nUse delta queries to get incremental changes (created, updated, deleted items) without reading the entire list.\n\n**Tool:** `ONE_DRIVE_LIST_SHAREPOINT_LIST_ITEMS_DELTA`\n\n**Key Parameters:**\n- `site_id` (required) -- Composite site ID\n- `list_id` (required) -- List GUID\n- `token` -- Omit for initial sync; pass `\"latest\"` for empty response with token; pass previous token for changes since\n- `expand` -- e.g., `\"fields($select=ColumnA,ColumnB)\"`\n- `top` -- Max items per response\n\n---\n\n### 6. Retrieve Site Page Content\n\nRead modern SharePoint Site Pages content including canvas web parts.\n\n**Tool:** `SHARE_POINT_GET_SITE_PAGE_CONTENT`\n\n**Key Parameters:**\n- `page_file_name` -- File name with `.aspx` extension, e.g., `\"Home.aspx\"`\n- `item_id` -- Alternative: list item ID of the page\n- `render_as` -- `\"raw\"` (default), `\"text\"`, or `\"html\"`\n- `site` -- Optional site name scope\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Site ID format** | Must be composite: `hostname,site-collection-guid,web-guid`. Incorrect format causes 400 errors. |\n| **Personal accounts unsupported** | `ONE_DRIVE_LIST_SITE_LISTS` and Graph-based tools only work with organizational M365 accounts, not personal MSA/Outlook.com accounts. |\n| **OData filter syntax** | SharePoint OData filters use specific syntax. Test filters incrementally; unsupported expressions may silently return empty results. |\n| **Pagination** | Use `skiptoken` for server-side paging in list operations. Incomplete pagination settings can miss results. |\n| **Folder paths** | Must use server-relative URLs (e.g., `/Shared Documents`) not absolute URLs. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `ONE_DRIVE_GET_SITE_DETAILS` | Get metadata for a SharePoint site |\n| `ONE_DRIVE_LIST_SITE_SUBSITES` | List subsites of a parent site |\n| `ONE_DRIVE_LIST_SITE_LISTS` | List all lists under a site (Graph API) |\n| `ONE_DRIVE_LIST_SHAREPOINT_LIST_ITEMS_DELTA` | Track incremental list changes |\n| `ONE_DRIVE_GET_SHAREPOINT_LIST_ITEMS` | Retrieve items from a list |\n| `ONE_DRIVE_LIST_DRIVES` | List available drives for a user/site/group |\n| `ONE_DRIVE_LIST_SITE_COLUMNS` | List column definitions for a site |\n| `SHARE_POINT_LIST_ALL_LISTS` | Retrieve all lists on a site (REST API) |\n| `SHARE_POINT_SHAREPOINT_CREATE_LIST` | Create a new SharePoint list |\n| `SHARE_POINT_SHAREPOINT_CREATE_FOLDER` | Create a folder in a document library |\n| `SHARE_POINT_LIST_FILES_IN_FOLDER` | List files in a folder |\n| `SHARE_POINT_SEARCH_QUERY` | Search content using KQL |\n| `SHARE_POINT_GET_SITE_PAGE_CONTENT` | Retrieve Site Page content |\n| `SHARE_POINT_GET_FOLDER_BY_SERVER_RELATIVE_URL` | Get folder metadata by path |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/share_point-automation/SKILL.md",
    "content": "---\nname: share_point-automation\ndescription: \"Automate SharePoint tasks via Rube MCP (Composio): document libraries, sites, lists, and content management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SharePoint Automation via Rube MCP\n\nAutomate SharePoint operations through Composio's SharePoint toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/share_point](https://composio.dev/toolkits/share_point)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SharePoint connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `share_point`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `share_point`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"document libraries, sites, lists, and content management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for SharePoint\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available SharePoint Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available SharePoint tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute SharePoint Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple SharePoint operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the SharePoint connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SharePoint-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `share_point` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/share_point](https://composio.dev/toolkits/share_point)\n"
  },
  {
    "path": "composio-skills/shipengine-automation/SKILL.md",
    "content": "---\nname: shipengine-automation\ndescription: \"Automate Shipengine tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Shipengine Automation via Rube MCP\n\nAutomate Shipengine operations through Composio's Shipengine toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/shipengine](https://composio.dev/toolkits/shipengine)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Shipengine connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `shipengine`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `shipengine`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Shipengine operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Shipengine task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"shipengine\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Shipengine-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `shipengine` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/short-io-automation/SKILL.md",
    "content": "---\nname: short-io-automation\ndescription: \"Automate Short IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Short IO Automation via Rube MCP\n\nAutomate Short IO operations through Composio's Short IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/short_io](https://composio.dev/toolkits/short_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Short IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `short_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `short_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Short IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Short IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"short_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Short IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `short_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/short-menu-automation/SKILL.md",
    "content": "---\nname: short-menu-automation\ndescription: \"Automate Short Menu tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Short Menu Automation via Rube MCP\n\nAutomate Short Menu operations through Composio's Short Menu toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/short_menu](https://composio.dev/toolkits/short_menu)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Short Menu connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `short_menu`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `short_menu`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Short Menu operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Short Menu task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"short_menu\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Short Menu-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `short_menu` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/shortcut-automation/SKILL.md",
    "content": "---\nname: Shortcut Automation\ndescription: \"Automate project management workflows in Shortcut -- create stories, manage tasks, track epics, and organize workflows through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Shortcut Automation\n\nAutomate your Shortcut project management operations directly from Claude Code. Create and list stories, add tasks and comments, batch-create stories, and navigate workflows -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/shortcut](https://composio.dev/toolkits/shortcut)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Shortcut account through the connection link provided\n3. Start automating your project management workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Create Stories\n\nAdd new stories to your Shortcut workspace with full configuration.\n\n**Tool:** `SHORTCUT_CREATE_STORY`\n\n```\nCreate a feature story called \"Add dark mode support\" in workflow state 500000001 with estimate 5 and label \"frontend\"\n```\n\nKey parameters for `SHORTCUT_CREATE_STORY`:\n- `name` (required) -- the story title\n- `workflow_state_id` -- the workflow state to place the story in (recommended over `project_id`)\n- `story_type` -- `\"feature\"`, `\"bug\"`, or `\"chore\"`\n- `description` -- story body/description\n- `estimate` -- numeric point estimate (or null for unestimated)\n- `epic_id` -- associate with an epic\n- `iteration_id` -- associate with an iteration\n- `labels` -- array of label objects with `name` (and optional `color`, `description`)\n- `owner_ids` -- array of member UUIDs to assign\n- `deadline` -- due date in ISO 8601 format\n- `tasks` -- inline task array with `description` and optional `complete`, `owner_ids`\n- `comments` -- inline comment array with `text`\n- `story_links` -- link stories with `verb` (`\"blocks\"`, `\"duplicates\"`, `\"relates to\"`)\n\n**Important:** Either `workflow_state_id` or `project_id` must be provided, but not both. `workflow_state_id` is recommended as Projects are being sunset in Shortcut.\n\n### 2. Batch Create Stories\n\nCreate multiple stories in a single API call.\n\n**Tool:** `SHORTCUT_CREATE_MULTIPLE_STORIES`\n\n```\nCreate 3 bug stories: \"Login page 500 error\", \"Cart total rounding issue\", and \"Search results empty state broken\"\n```\n\n- Requires `stories` array where each element follows the same schema as `SHORTCUT_CREATE_STORY`\n- Each story in the array requires `name`\n- Efficient for bulk imports, sprint planning, or template-based story creation\n\n### 3. List Stories in a Project\n\nRetrieve all stories within a specific project.\n\n**Tool:** `SHORTCUT_LIST_STORIES`\n\n```\nList all stories in project 42 with their descriptions\n```\n\n- Requires `project__public__id` (integer project ID)\n- Optional `includes_description: true` to include story descriptions in the response\n- Returns all stories with their attributes (status, type, estimate, etc.)\n\n### 4. Manage Story Tasks\n\nCreate tasks (checklists) within stories for tracking sub-work.\n\n**Tool:** `SHORTCUT_CREATE_TASK`\n\n```\nAdd a task \"Write unit tests for dark mode toggle\" to story 12345\n```\n\nKey parameters:\n- `story__public__id` (required) -- the parent story ID\n- `description` (required) -- the task description\n- `complete` -- boolean, defaults to false\n- `owner_ids` -- array of member UUIDs to assign the task\n- `external_id` -- ID from an external tool if imported\n\n### 5. Add Story Comments\n\nPost comments on stories for discussion and documentation.\n\n**Tool:** `SHORTCUT_CREATE_STORY_COMMENT`\n\n```\nAdd a comment to story 12345: \"Reviewed the implementation -- looks good, but needs accessibility testing\"\n```\n\nKey parameters:\n- `story__public__id` (required) -- the story ID\n- `text` (required) -- the comment body\n- `author_id` -- member UUID (defaults to API token owner)\n- `parent_id` -- ID of parent comment for threaded replies\n\n### 6. Workflow and Project Discovery\n\nList workflows and projects to resolve IDs for story creation.\n\n**Tools:** `SHORTCUT_LIST_WORKFLOWS`, `SHORTCUT_LIST_PROJECTS`\n\n```\nShow me all workflows in our Shortcut workspace so I can find the right workflow state ID\n```\n\n- `SHORTCUT_LIST_WORKFLOWS` returns all workflows with their states (IDs, names, types)\n- `SHORTCUT_LIST_PROJECTS` returns all projects with their attributes\n- Use these to discover valid `workflow_state_id` and `project_id` values before creating stories\n\n---\n\n## Known Pitfalls\n\n- **`workflow_state_id` vs `project_id`:** `SHORTCUT_CREATE_STORY` requires exactly one of these. Providing both or neither causes a rejection. Prefer `workflow_state_id` since Projects are being sunset.\n- **Projects are being sunset:** Shortcut is deprecating Projects in favor of workflow-based organization. Use `workflow_state_id` for new stories.\n- **Label creation is inline:** Labels in the `labels` array are created on-the-fly if they do not exist. The `name` field is required for each label object.\n- **Story type defaults:** If `story_type` is omitted, it defaults to `\"feature\"`. Always set it explicitly for bugs and chores.\n- **Batch limits:** `SHORTCUT_CREATE_MULTIPLE_STORIES` processes all stories in a single request. Very large batches may time out -- keep batches under 25 stories.\n- **Integer IDs for stories/projects:** Story and project IDs are integers, not UUIDs. Member and group IDs are UUIDs. Mixing these formats causes errors.\n- **`move_to` positioning:** The `move_to` field (`\"first\"` or `\"last\"`) moves the story within its workflow state, not across states.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `SHORTCUT_CREATE_STORY` | Create a single story (requires `name` + `workflow_state_id` or `project_id`) |\n| `SHORTCUT_CREATE_MULTIPLE_STORIES` | Batch-create multiple stories (requires `stories` array) |\n| `SHORTCUT_LIST_STORIES` | List stories in a project (requires `project__public__id`) |\n| `SHORTCUT_CREATE_TASK` | Create a task in a story (requires `story__public__id`, `description`) |\n| `SHORTCUT_CREATE_STORY_COMMENT` | Add a comment to a story (requires `story__public__id`, `text`) |\n| `SHORTCUT_CREATE_STORY_FROM_TEMPLATE` | Create a story from a template |\n| `SHORTCUT_LIST_WORKFLOWS` | List all workflows and their states |\n| `SHORTCUT_LIST_PROJECTS` | List all projects |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/shorten-rest-automation/SKILL.md",
    "content": "---\nname: shorten-rest-automation\ndescription: \"Automate Shorten Rest tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Shorten Rest Automation via Rube MCP\n\nAutomate Shorten Rest operations through Composio's Shorten Rest toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/shorten_rest](https://composio.dev/toolkits/shorten_rest)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Shorten Rest connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `shorten_rest`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `shorten_rest`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Shorten Rest operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Shorten Rest task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"shorten_rest\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Shorten Rest-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `shorten_rest` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/shortpixel-automation/SKILL.md",
    "content": "---\nname: shortpixel-automation\ndescription: \"Automate Shortpixel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Shortpixel Automation via Rube MCP\n\nAutomate Shortpixel operations through Composio's Shortpixel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/shortpixel](https://composio.dev/toolkits/shortpixel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Shortpixel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `shortpixel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `shortpixel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Shortpixel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Shortpixel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"shortpixel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Shortpixel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `shortpixel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/shotstack-automation/SKILL.md",
    "content": "---\nname: shotstack-automation\ndescription: \"Automate Shotstack tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Shotstack Automation via Rube MCP\n\nAutomate Shotstack operations through Composio's Shotstack toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/shotstack](https://composio.dev/toolkits/shotstack)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Shotstack connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `shotstack`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `shotstack`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Shotstack operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Shotstack task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"shotstack\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Shotstack-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `shotstack` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sidetracker-automation/SKILL.md",
    "content": "---\nname: sidetracker-automation\ndescription: \"Automate Sidetracker tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sidetracker Automation via Rube MCP\n\nAutomate Sidetracker operations through Composio's Sidetracker toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sidetracker](https://composio.dev/toolkits/sidetracker)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sidetracker connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sidetracker`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sidetracker`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sidetracker operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sidetracker task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sidetracker\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sidetracker-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sidetracker` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/signaturely-automation/SKILL.md",
    "content": "---\nname: signaturely-automation\ndescription: \"Automate Signaturely tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Signaturely Automation via Rube MCP\n\nAutomate Signaturely operations through Composio's Signaturely toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/signaturely](https://composio.dev/toolkits/signaturely)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Signaturely connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `signaturely`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `signaturely`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Signaturely operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Signaturely task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"signaturely\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Signaturely-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `signaturely` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/signpath-automation/SKILL.md",
    "content": "---\nname: signpath-automation\ndescription: \"Automate Signpath tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Signpath Automation via Rube MCP\n\nAutomate Signpath operations through Composio's Signpath toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/signpath](https://composio.dev/toolkits/signpath)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Signpath connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `signpath`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `signpath`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Signpath operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Signpath task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"signpath\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Signpath-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `signpath` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/signwell-automation/SKILL.md",
    "content": "---\nname: signwell-automation\ndescription: \"Automate Signwell tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Signwell Automation via Rube MCP\n\nAutomate Signwell operations through Composio's Signwell toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/signwell](https://composio.dev/toolkits/signwell)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Signwell connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `signwell`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `signwell`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Signwell operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Signwell task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"signwell\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Signwell-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `signwell` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/similarweb-digitalrank-api-automation/SKILL.md",
    "content": "---\nname: similarweb-digitalrank-api-automation\ndescription: \"Automate SimilarWeb tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SimilarWeb Automation via Rube MCP\n\nAutomate SimilarWeb operations through Composio's SimilarWeb toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/similarweb_digitalrank_api](https://composio.dev/toolkits/similarweb_digitalrank_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SimilarWeb connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"SimilarWeb operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific SimilarWeb task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"similarweb_digitalrank_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SimilarWeb-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/similarweb_digitalrank_api-automation/SKILL.md",
    "content": "---\nname: similarweb_digitalrank_api-automation\ndescription: \"Automate SimilarWeb tasks via Rube MCP (Composio): website traffic, rankings, and digital market intelligence. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SimilarWeb Automation via Rube MCP\n\nAutomate SimilarWeb operations through Composio's SimilarWeb toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/similarweb_digitalrank_api](https://composio.dev/toolkits/similarweb_digitalrank_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SimilarWeb connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"website traffic, rankings, and digital market intelligence\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for SimilarWeb\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available SimilarWeb Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available SimilarWeb tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute SimilarWeb Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple SimilarWeb operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the SimilarWeb connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SimilarWeb-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `similarweb_digitalrank_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/similarweb_digitalrank_api](https://composio.dev/toolkits/similarweb_digitalrank_api)\n"
  },
  {
    "path": "composio-skills/simla-com-automation/SKILL.md",
    "content": "---\nname: simla-com-automation\ndescription: \"Automate Simla Com tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Simla Com Automation via Rube MCP\n\nAutomate Simla Com operations through Composio's Simla Com toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/simla_com](https://composio.dev/toolkits/simla_com)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Simla Com connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `simla_com`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `simla_com`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Simla Com operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Simla Com task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"simla_com\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Simla Com-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `simla_com` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/simple-analytics-automation/SKILL.md",
    "content": "---\nname: simple-analytics-automation\ndescription: \"Automate Simple Analytics tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Simple Analytics Automation via Rube MCP\n\nAutomate Simple Analytics operations through Composio's Simple Analytics toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/simple_analytics](https://composio.dev/toolkits/simple_analytics)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Simple Analytics connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `simple_analytics`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `simple_analytics`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Simple Analytics operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Simple Analytics task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"simple_analytics\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Simple Analytics-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `simple_analytics` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/simplesat-automation/SKILL.md",
    "content": "---\nname: simplesat-automation\ndescription: \"Automate Simplesat tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Simplesat Automation via Rube MCP\n\nAutomate Simplesat operations through Composio's Simplesat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/simplesat](https://composio.dev/toolkits/simplesat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Simplesat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `simplesat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `simplesat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Simplesat operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Simplesat task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"simplesat\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Simplesat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `simplesat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sitespeakai-automation/SKILL.md",
    "content": "---\nname: sitespeakai-automation\ndescription: \"Automate Sitespeakai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sitespeakai Automation via Rube MCP\n\nAutomate Sitespeakai operations through Composio's Sitespeakai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sitespeakai](https://composio.dev/toolkits/sitespeakai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sitespeakai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sitespeakai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sitespeakai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sitespeakai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sitespeakai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sitespeakai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sitespeakai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sitespeakai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/skyfire-automation/SKILL.md",
    "content": "---\nname: skyfire-automation\ndescription: \"Automate Skyfire tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Skyfire Automation via Rube MCP\n\nAutomate Skyfire operations through Composio's Skyfire toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/skyfire](https://composio.dev/toolkits/skyfire)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Skyfire connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `skyfire`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `skyfire`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Skyfire operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Skyfire task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"skyfire\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Skyfire-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `skyfire` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/slackbot-automation/SKILL.md",
    "content": "---\nname: slackbot-automation\ndescription: \"Automate Slackbot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Slackbot Automation via Rube MCP\n\nAutomate Slackbot operations through Composio's Slackbot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/slackbot](https://composio.dev/toolkits/slackbot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Slackbot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `slackbot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `slackbot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Slackbot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Slackbot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"slackbot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Slackbot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `slackbot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/smartproxy-automation/SKILL.md",
    "content": "---\nname: smartproxy-automation\ndescription: \"Automate Smartproxy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Smartproxy Automation via Rube MCP\n\nAutomate Smartproxy operations through Composio's Smartproxy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/smartproxy](https://composio.dev/toolkits/smartproxy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Smartproxy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `smartproxy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `smartproxy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Smartproxy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Smartproxy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"smartproxy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Smartproxy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `smartproxy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/smartrecruiters-automation/SKILL.md",
    "content": "---\nname: smartrecruiters-automation\ndescription: \"Automate Smartrecruiters tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Smartrecruiters Automation via Rube MCP\n\nAutomate Smartrecruiters operations through Composio's Smartrecruiters toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/smartrecruiters](https://composio.dev/toolkits/smartrecruiters)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Smartrecruiters connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `smartrecruiters`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `smartrecruiters`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Smartrecruiters operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Smartrecruiters task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"smartrecruiters\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Smartrecruiters-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `smartrecruiters` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sms-alert-automation/SKILL.md",
    "content": "---\nname: sms-alert-automation\ndescription: \"Automate SMS Alert tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SMS Alert Automation via Rube MCP\n\nAutomate SMS Alert operations through Composio's SMS Alert toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sms_alert](https://composio.dev/toolkits/sms_alert)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SMS Alert connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sms_alert`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sms_alert`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"SMS Alert operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific SMS Alert task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sms_alert\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SMS Alert-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sms_alert` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/smtp2go-automation/SKILL.md",
    "content": "---\nname: smtp2go-automation\ndescription: \"Automate Smtp2go tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Smtp2go Automation via Rube MCP\n\nAutomate Smtp2go operations through Composio's Smtp2go toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/smtp2go](https://composio.dev/toolkits/smtp2go)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Smtp2go connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `smtp2go`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `smtp2go`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Smtp2go operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Smtp2go task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"smtp2go\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Smtp2go-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `smtp2go` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/smugmug-automation/SKILL.md",
    "content": "---\nname: smugmug-automation\ndescription: \"Automate Smugmug tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Smugmug Automation via Rube MCP\n\nAutomate Smugmug operations through Composio's Smugmug toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/smugmug](https://composio.dev/toolkits/smugmug)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Smugmug connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `smugmug`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `smugmug`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Smugmug operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Smugmug task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"smugmug\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Smugmug-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `smugmug` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/snowflake-automation/SKILL.md",
    "content": "---\nname: Snowflake Automation\ndescription: \"Automate Snowflake data warehouse operations -- list databases, schemas, and tables, execute SQL statements, and manage data workflows via the Composio MCP integration.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Snowflake Automation\n\nAutomate your Snowflake data warehouse workflows -- discover databases, browse schemas and tables, execute arbitrary SQL (SELECT, DDL, DML), and integrate Snowflake data operations into cross-app pipelines.\n\n**Toolkit docs:** [composio.dev/toolkits/snowflake](https://composio.dev/toolkits/snowflake)\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client: `https://rube.app/mcp`\n2. Connect your Snowflake account when prompted (account credentials or key-pair authentication)\n3. Start using the workflows below\n\n---\n\n## Core Workflows\n\n### 1. List Databases\n\nUse `SNOWFLAKE_SHOW_DATABASES` to discover available databases with optional filtering and Time Travel support.\n\n```\nTool: SNOWFLAKE_SHOW_DATABASES\nInputs:\n  - like_pattern: string (SQL wildcard, e.g., \"%test%\") -- case-insensitive\n  - starts_with: string (e.g., \"PROD\") -- case-sensitive\n  - limit: integer (max 10000)\n  - history: boolean (include dropped databases within Time Travel retention)\n  - terse: boolean (return subset of columns: created_on, name, kind, database_name, schema_name)\n  - role: string (role to use for execution)\n  - warehouse: string (optional, not required for SHOW DATABASES)\n  - timeout: integer (seconds)\n```\n\n### 2. Browse Schemas\n\nUse `SNOWFLAKE_SHOW_SCHEMAS` to list schemas within a database or across the account.\n\n```\nTool: SNOWFLAKE_SHOW_SCHEMAS\nInputs:\n  - database: string (database context)\n  - in_scope: \"ACCOUNT\" | \"DATABASE\" | \"<specific_database_name>\"\n  - like_pattern: string (SQL wildcard filter)\n  - starts_with: string (case-sensitive prefix)\n  - limit: integer (max 10000)\n  - history: boolean (include dropped schemas)\n  - terse: boolean (subset columns only)\n  - role, warehouse, timeout: string/integer (optional)\n```\n\n### 3. List Tables\n\nUse `SNOWFLAKE_SHOW_TABLES` to discover tables with metadata including row counts, sizes, and clustering keys.\n\n```\nTool: SNOWFLAKE_SHOW_TABLES\nInputs:\n  - database: string (database context)\n  - schema: string (schema context)\n  - in_scope: \"ACCOUNT\" | \"DATABASE\" | \"SCHEMA\" | \"<specific_name>\"\n  - like_pattern: string (e.g., \"%customer%\")\n  - starts_with: string (e.g., \"FACT\", \"DIM\", \"TEMP\")\n  - limit: integer (max 10000)\n  - history: boolean (include dropped tables)\n  - terse: boolean (subset columns only)\n  - role, warehouse, timeout: string/integer (optional)\n```\n\n### 4. Execute SQL Statements\n\nUse `SNOWFLAKE_EXECUTE_SQL` for SELECT queries, DDL (CREATE/ALTER/DROP), and DML (INSERT/UPDATE/DELETE) with parameterized bindings.\n\n```\nTool: SNOWFLAKE_EXECUTE_SQL\nInputs:\n  - statement: string (required) -- SQL statement(s), semicolon-separated for multi-statement\n  - database: string (case-sensitive, falls back to DEFAULT_NAMESPACE)\n  - schema_name: string (case-sensitive)\n  - warehouse: string (case-sensitive, required for compute-bound queries)\n  - role: string (case-sensitive, falls back to DEFAULT_ROLE)\n  - bindings: object (parameterized query values to prevent SQL injection)\n  - parameters: object (Snowflake session-level parameters)\n  - timeout: integer (seconds; 0 = max 604800s)\n```\n\n**Examples:**\n- `\"SELECT * FROM my_table LIMIT 100;\"`\n- `\"CREATE TABLE test (id INT, name STRING);\"`\n- `\"ALTER SESSION SET QUERY_TAG='mytag'; SELECT COUNT(*) FROM my_table;\"`\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| Case sensitivity | Database, schema, warehouse, and role names are case-sensitive in `SNOWFLAKE_EXECUTE_SQL`. |\n| Warehouse required for compute | SELECT and DML queries require a running warehouse. SHOW commands do not. |\n| Multi-statement execution | Multiple statements separated by semicolons execute in sequence automatically. |\n| SQL injection prevention | Always use the `bindings` parameter for user-supplied values to prevent injection attacks. |\n| Pagination with LIMIT | `SHOW` commands support `limit` (max 10000) and `from_name` for cursor-based pagination. |\n| Time Travel | Set `history: true` to include dropped objects still within the retention period. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `SNOWFLAKE_SHOW_DATABASES` | List databases with filtering and Time Travel support |\n| `SNOWFLAKE_SHOW_SCHEMAS` | List schemas within a database or account-wide |\n| `SNOWFLAKE_SHOW_TABLES` | List tables with metadata (row count, size, clustering) |\n| `SNOWFLAKE_EXECUTE_SQL` | Execute SQL: SELECT, DDL, DML with parameterized bindings |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sourcegraph-automation/SKILL.md",
    "content": "---\nname: sourcegraph-automation\ndescription: \"Automate Sourcegraph tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sourcegraph Automation via Rube MCP\n\nAutomate Sourcegraph operations through Composio's Sourcegraph toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sourcegraph](https://composio.dev/toolkits/sourcegraph)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sourcegraph connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sourcegraph`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sourcegraph`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sourcegraph operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sourcegraph task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sourcegraph\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sourcegraph-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sourcegraph` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/splitwise-automation/SKILL.md",
    "content": "---\nname: splitwise-automation\ndescription: \"Automate Splitwise tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Splitwise Automation via Rube MCP\n\nAutomate Splitwise operations through Composio's Splitwise toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/splitwise](https://composio.dev/toolkits/splitwise)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Splitwise connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `splitwise`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `splitwise`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Splitwise operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Splitwise task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"splitwise\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Splitwise-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `splitwise` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/spoki-automation/SKILL.md",
    "content": "---\nname: spoki-automation\ndescription: \"Automate Spoki tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Spoki Automation via Rube MCP\n\nAutomate Spoki operations through Composio's Spoki toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/spoki](https://composio.dev/toolkits/spoki)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Spoki connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `spoki`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `spoki`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Spoki operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Spoki task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"spoki\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Spoki-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `spoki` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/spondyr-automation/SKILL.md",
    "content": "---\nname: spondyr-automation\ndescription: \"Automate Spondyr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Spondyr Automation via Rube MCP\n\nAutomate Spondyr operations through Composio's Spondyr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/spondyr](https://composio.dev/toolkits/spondyr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Spondyr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `spondyr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `spondyr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Spondyr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Spondyr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"spondyr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Spondyr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `spondyr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/spotify-automation/SKILL.md",
    "content": "---\nname: Spotify Automation\ndescription: \"Automate Spotify workflows including playlist management, music search, playback control, and user profile access via Composio\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Spotify Automation\n\nAutomate Spotify operations -- manage playlists, search the music catalog, control playback, browse albums and tracks, and access user profiles -- all orchestrated through the Composio MCP integration.\n\n**Toolkit docs:** [composio.dev/toolkits/spotify](https://composio.dev/toolkits/spotify)\n\n---\n\n## Setup\n\n1. Connect your Spotify account through the Composio MCP server at `https://rube.app/mcp`\n2. The agent will prompt you with an authentication link if no active connection exists\n3. Once connected, all `SPOTIFY_*` tools become available for execution\n4. **Note:** Some features (playback control) require a Spotify Premium subscription\n\n---\n\n## Core Workflows\n\n### 1. Get Current User Profile\nRetrieve comprehensive profile information for the authenticated Spotify user.\n\n**Tool:** `SPOTIFY_GET_CURRENT_USER_S_PROFILE`\n\n```\nNo parameters required.\nReturns: display name, email, country, subscription level (premium/free),\nexplicit content settings, profile images, follower count, and Spotify URIs.\nRequired scopes: user-read-private, user-read-email.\n```\n\n---\n\n### 2. Search the Spotify Catalog\nFind albums, artists, playlists, tracks, shows, episodes, or audiobooks by keyword.\n\n**Tool:** `SPOTIFY_SEARCH_FOR_ITEM`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `q` | string | Yes | Search query keywords |\n| `type` | array | Yes | Item types: `album`, `artist`, `playlist`, `track`, `show`, `episode`, `audiobook` |\n| `limit` | integer | No | Results to return (default: 20) |\n| `offset` | integer | No | Offset for pagination (default: 0) |\n| `market` | string | No | ISO 3166-1 alpha-2 country code |\n| `include_external` | string | No | Set to `audio` to include external content |\n\n**Note:** Audiobooks are only available in US, UK, Canada, Ireland, New Zealand, and Australia.\n\n---\n\n### 3. Manage Playlists\nBrowse, create, modify, and populate playlists.\n\n**Get a user's playlists:**\n\n**Tool:** `SPOTIFY_GET_USER_S_PLAYLISTS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `user_id` | string | Yes | Spotify user ID |\n| `limit` | integer | No | Max playlists, 1-50 (default: 20) |\n| `offset` | integer | No | Pagination offset, 0-100000 (default: 0) |\n\n**Get current user's playlists:**\n\n**Tool:** `SPOTIFY_GET_CURRENT_USER_S_PLAYLISTS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `limit` | integer | No | Max playlists, 1-50 (default: 20) |\n| `offset` | integer | No | Pagination offset, 0-100000 (default: 0) |\n\n**Get playlist details:**\n\n**Tool:** `SPOTIFY_GET_PLAYLIST`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `playlist_id` | string | Yes | Spotify playlist ID (e.g., `3cEYpjA9oz9GiPac4AsH4n`) |\n| `fields` | string | No | Comma-separated field filter to reduce response size |\n| `market` | string | No | ISO country code for market-specific content |\n| `additional_types` | string | No | `track,episode` to include podcast episodes |\n\n**Update playlist details:**\n\n**Tool:** `SPOTIFY_CHANGE_PLAYLIST_DETAILS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `playlist_id` | string | Yes | Playlist ID (must be owned by current user) |\n| `name` | string | No | New playlist name |\n| `description` | string | No | New playlist description |\n| `public` | boolean | No | Public/private toggle |\n| `collaborative` | boolean | No | Collaborative mode (only on non-public playlists) |\n\n---\n\n### 4. Browse Playlist Items & Add Tracks\nView tracks in a playlist and add new items.\n\n**Tool:** `SPOTIFY_GET_PLAYLIST_ITEMS`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `playlist_id` | string | Yes | Spotify playlist ID |\n| `limit` | integer | No | Items per page, 1-50 (default: 20) |\n| `offset` | integer | No | Pagination offset (default: 0) |\n| `fields` | string | No | Field filter (e.g., `items(track(name,id))`) |\n| `market` | string | No | ISO country code |\n| `additional_types` | string | No | `track,episode` for podcast episodes |\n\n**Tool:** `SPOTIFY_ADD_ITEMS_TO_PLAYLIST`\n\nAdd tracks or episodes to a playlist using Spotify URIs.\n\n---\n\n### 5. Get Track & Album Details\nRetrieve catalog information for individual tracks and albums.\n\n**Tool:** `SPOTIFY_GET_TRACK` -- Get details for a single track by Spotify ID.\n\n**Tool:** `SPOTIFY_GET_ALBUM` -- Get comprehensive album data including track listing, artist info, cover art, and popularity.\n\n---\n\n### 6. Control Playback\nStart, resume, or change playback on the user's active device.\n\n**Tool:** `SPOTIFY_START_RESUME_PLAYBACK`\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `context_uri` | string | No | Spotify URI of album, artist, or playlist (cannot combine with `uris`) |\n| `uris` | array | No | List of track URIs to play (cannot combine with `context_uri`) |\n| `offset` | object | No | Starting position: `{position: 5}` or `{uri: 'spotify:track:...'}` |\n| `position_ms` | integer | No | Start position in milliseconds |\n| `device_id` | string | No | Target device ID (defaults to active device) |\n\n**Requirements:** Spotify Premium subscription and at least one active device.\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| **Premium required for playback** | `SPOTIFY_START_RESUME_PLAYBACK` returns 403 if the user does not have Spotify Premium |\n| **Active device required** | Playback control returns 404 if no Spotify device (mobile, desktop, web, speaker) is active |\n| **context_uri vs uris are exclusive** | Cannot use both `context_uri` and `uris` in the same playback call |\n| **Collaborative playlists** | `collaborative` can only be set to `true` on non-public playlists (`public` must be `false`) |\n| **Playlist ownership** | `SPOTIFY_CHANGE_PLAYLIST_DETAILS` only works on playlists owned by the authenticated user |\n| **Audiobook market restrictions** | Audiobooks via search are only available in US, UK, Canada, Ireland, New Zealand, and Australia |\n| **Max 11000 playlists** | Users are limited to approximately 11,000 playlists via `SPOTIFY_CREATE_PLAYLIST` |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Purpose |\n|-----------|---------|\n| `SPOTIFY_GET_CURRENT_USER_S_PROFILE` | Get authenticated user's profile |\n| `SPOTIFY_SEARCH_FOR_ITEM` | Search catalog for tracks, albums, artists, etc. |\n| `SPOTIFY_GET_USER_S_PLAYLISTS` | Get playlists for any user |\n| `SPOTIFY_GET_CURRENT_USER_S_PLAYLISTS` | Get current user's playlists |\n| `SPOTIFY_GET_PLAYLIST` | Get detailed playlist info |\n| `SPOTIFY_GET_PLAYLIST_ITEMS` | List tracks/episodes in a playlist |\n| `SPOTIFY_CHANGE_PLAYLIST_DETAILS` | Update playlist name, description, visibility |\n| `SPOTIFY_CREATE_PLAYLIST` | Create a new playlist |\n| `SPOTIFY_ADD_ITEMS_TO_PLAYLIST` | Add tracks/episodes to a playlist |\n| `SPOTIFY_GET_TRACK` | Get track details by ID |\n| `SPOTIFY_GET_ALBUM` | Get album details by ID |\n| `SPOTIFY_START_RESUME_PLAYBACK` | Start or resume playback on a device |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/spotlightr-automation/SKILL.md",
    "content": "---\nname: spotlightr-automation\ndescription: \"Automate Spotlightr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Spotlightr Automation via Rube MCP\n\nAutomate Spotlightr operations through Composio's Spotlightr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/spotlightr](https://composio.dev/toolkits/spotlightr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Spotlightr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `spotlightr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `spotlightr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Spotlightr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Spotlightr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"spotlightr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Spotlightr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `spotlightr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sslmate-cert-spotter-api-automation/SKILL.md",
    "content": "---\nname: sslmate-cert-spotter-api-automation\ndescription: \"Automate Sslmate Cert Spotter API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sslmate Cert Spotter API Automation via Rube MCP\n\nAutomate Sslmate Cert Spotter API operations through Composio's Sslmate Cert Spotter API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sslmate_cert_spotter_api](https://composio.dev/toolkits/sslmate_cert_spotter_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sslmate Cert Spotter API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sslmate_cert_spotter_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sslmate_cert_spotter_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sslmate Cert Spotter API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sslmate Cert Spotter API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sslmate_cert_spotter_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sslmate Cert Spotter API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sslmate_cert_spotter_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/stack-exchange-automation/SKILL.md",
    "content": "---\nname: stack-exchange-automation\ndescription: \"Automate Stack Exchange tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Stack Exchange Automation via Rube MCP\n\nAutomate Stack Exchange operations through Composio's Stack Exchange toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/stack_exchange](https://composio.dev/toolkits/stack_exchange)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Stack Exchange connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `stack_exchange`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `stack_exchange`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Stack Exchange operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Stack Exchange task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"stack_exchange\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Stack Exchange-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `stack_exchange` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/stannp-automation/SKILL.md",
    "content": "---\nname: stannp-automation\ndescription: \"Automate Stannp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Stannp Automation via Rube MCP\n\nAutomate Stannp operations through Composio's Stannp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/stannp](https://composio.dev/toolkits/stannp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Stannp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `stannp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `stannp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Stannp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Stannp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"stannp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Stannp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `stannp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/starton-automation/SKILL.md",
    "content": "---\nname: starton-automation\ndescription: \"Automate Starton tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Starton Automation via Rube MCP\n\nAutomate Starton operations through Composio's Starton toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/starton](https://composio.dev/toolkits/starton)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Starton connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `starton`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `starton`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Starton operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Starton task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"starton\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Starton-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `starton` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/statuscake-automation/SKILL.md",
    "content": "---\nname: statuscake-automation\ndescription: \"Automate Statuscake tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Statuscake Automation via Rube MCP\n\nAutomate Statuscake operations through Composio's Statuscake toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/statuscake](https://composio.dev/toolkits/statuscake)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Statuscake connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `statuscake`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `statuscake`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Statuscake operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Statuscake task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"statuscake\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Statuscake-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `statuscake` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/storeganise-automation/SKILL.md",
    "content": "---\nname: storeganise-automation\ndescription: \"Automate Storeganise tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Storeganise Automation via Rube MCP\n\nAutomate Storeganise operations through Composio's Storeganise toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/storeganise](https://composio.dev/toolkits/storeganise)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Storeganise connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `storeganise`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `storeganise`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Storeganise operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Storeganise task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"storeganise\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Storeganise-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `storeganise` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/storerocket-automation/SKILL.md",
    "content": "---\nname: storerocket-automation\ndescription: \"Automate Storerocket tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Storerocket Automation via Rube MCP\n\nAutomate Storerocket operations through Composio's Storerocket toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/storerocket](https://composio.dev/toolkits/storerocket)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Storerocket connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `storerocket`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `storerocket`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Storerocket operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Storerocket task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"storerocket\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Storerocket-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `storerocket` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/stormglass-io-automation/SKILL.md",
    "content": "---\nname: stormglass-io-automation\ndescription: \"Automate Stormglass IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Stormglass IO Automation via Rube MCP\n\nAutomate Stormglass IO operations through Composio's Stormglass IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/stormglass_io](https://composio.dev/toolkits/stormglass_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Stormglass IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `stormglass_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `stormglass_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Stormglass IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Stormglass IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"stormglass_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Stormglass IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `stormglass_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/strava-automation/SKILL.md",
    "content": "---\nname: strava-automation\ndescription: \"Automate Strava tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Strava Automation via Rube MCP\n\nAutomate Strava operations through Composio's Strava toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/strava](https://composio.dev/toolkits/strava)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Strava connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `strava`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `strava`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Strava operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Strava task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"strava\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Strava-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `strava` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/streamtime-automation/SKILL.md",
    "content": "---\nname: streamtime-automation\ndescription: \"Automate Streamtime tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Streamtime Automation via Rube MCP\n\nAutomate Streamtime operations through Composio's Streamtime toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/streamtime](https://composio.dev/toolkits/streamtime)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Streamtime connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `streamtime`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `streamtime`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Streamtime operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Streamtime task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"streamtime\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Streamtime-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `streamtime` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/supadata-automation/SKILL.md",
    "content": "---\nname: supadata-automation\ndescription: \"Automate Supadata tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Supadata Automation via Rube MCP\n\nAutomate Supadata operations through Composio's Supadata toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/supadata](https://composio.dev/toolkits/supadata)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Supadata connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `supadata`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `supadata`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Supadata operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Supadata task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"supadata\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Supadata-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `supadata` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/superchat-automation/SKILL.md",
    "content": "---\nname: superchat-automation\ndescription: \"Automate Superchat tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Superchat Automation via Rube MCP\n\nAutomate Superchat operations through Composio's Superchat toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/superchat](https://composio.dev/toolkits/superchat)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Superchat connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `superchat`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `superchat`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Superchat operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Superchat task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"superchat\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Superchat-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `superchat` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/supportbee-automation/SKILL.md",
    "content": "---\nname: supportbee-automation\ndescription: \"Automate Supportbee tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Supportbee Automation via Rube MCP\n\nAutomate Supportbee operations through Composio's Supportbee toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/supportbee](https://composio.dev/toolkits/supportbee)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Supportbee connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `supportbee`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `supportbee`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Supportbee operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Supportbee task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"supportbee\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Supportbee-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `supportbee` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/supportivekoala-automation/SKILL.md",
    "content": "---\nname: supportivekoala-automation\ndescription: \"Automate Supportivekoala tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Supportivekoala Automation via Rube MCP\n\nAutomate Supportivekoala operations through Composio's Supportivekoala toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/supportivekoala](https://composio.dev/toolkits/supportivekoala)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Supportivekoala connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `supportivekoala`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `supportivekoala`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Supportivekoala operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Supportivekoala task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"supportivekoala\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Supportivekoala-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `supportivekoala` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/survey-monkey-automation/SKILL.md",
    "content": "---\nname: SurveyMonkey Automation\ndescription: \"Automate SurveyMonkey survey creation, response collection, collector management, and survey discovery through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# SurveyMonkey Automation\n\nAutomate SurveyMonkey survey workflows -- create surveys, list and search existing surveys, manage collectors and distribution links, retrieve responses, and inspect survey details -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/survey_monkey](https://composio.dev/toolkits/survey_monkey)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your SurveyMonkey account when prompted (OAuth flow via Composio)\n3. Start issuing natural language commands for SurveyMonkey automation\n\n---\n\n## Core Workflows\n\n### 1. Create a New Survey\n\nCreate a new empty survey that can be further configured with questions and pages.\n\n**Tool:** `SURVEY_MONKEY_CREATE_SURVEY`\n\nKey parameters:\n- `title` -- survey title displayed to respondents (required)\n- `nickname` -- optional internal name for organizing surveys (not shown to respondents)\n- `language` -- ISO 639-1 language code (default `en`); examples: `es`, `fr`, `de`\n- `footer` -- whether to display SurveyMonkey branding footer (default `true`)\n\n> The created survey starts with one empty page and no questions. Use the returned `survey_id` with other actions to add content and configure collectors.\n\nExample prompt:\n> \"Create a new survey titled 'Customer Satisfaction Q1 2026'\"\n\n---\n\n### 2. List and Search Surveys\n\nEnumerate all surveys in your account with filtering, sorting, and pagination.\n\n**Tool:** `SURVEY_MONKEY_GET_SURVEYS`\n\nKey parameters:\n- `title` -- search by survey title (partial match)\n- `sort_by` -- sort by `title`, `date_modified`, or `num_responses`\n- `sort_order` -- `ASC` or `DESC`\n- `page` / `per_page` -- pagination controls (default 50 per page, max 100)\n- `include` -- additional fields: `response_count`, `date_modified`, `date_created`, `question_count`, `page_count`, `category`, `language`, `folder_id`\n- `folder_id` -- filter to surveys in a specific folder\n- `start_modified_at` / `end_modified_at` -- date range filter (format: `YYYY-MM-DDTHH:MM:SS`)\n\nExample prompt:\n> \"List all my surveys sorted by most recent modification, include response counts\"\n\n---\n\n### 3. Get Survey Details\n\nRetrieve comprehensive metadata for a specific survey including configuration, question/page counts, response counts, and all relevant URLs.\n\n**Tool:** `SURVEY_MONKEY_GET_SURVEY_DETAILS`\n\nKey parameters:\n- `survey_id` -- the unique survey identifier (required)\n\nReturns: title, language, question_count, page_count, response_count, URLs for preview/edit/analyze/collect, button text, and timestamps.\n\nExample prompt:\n> \"Show me the full details and response count for survey 123456789\"\n\n---\n\n### 4. Manage Collectors and Distribution Links\n\nRetrieve collectors (distribution channels) for a survey to get shareable links and monitor response progress.\n\n**Tool:** `SURVEY_MONKEY_GET_COLLECTORS`\n\nKey parameters:\n- `survey_id` -- the survey to get collectors for (required)\n- `include` -- additional fields: `type`, `status`, `response_count`, `date_created`, `date_modified`, `url`\n- `name` -- partial match filter on collector name\n- `sort_by` -- sort by `id`, `date_modified`, `type`, `status`, or `name`\n- `sort_order` -- `ASC` or `DESC`\n- `page` / `per_page` -- pagination (default 50, max 1000)\n- `start_date` / `end_date` -- filter by creation date (format: `YYYY-MM-DDTHH:MM:SS`)\n\nExample prompt:\n> \"Get all collectors for survey 123456789, include URLs and response counts\"\n\n---\n\n### 5. Retrieve Survey Responses\n\nFetch response data for a specific survey with comprehensive filtering options.\n\n**Tool:** `SURVEY_MONKEY_GET_RESPONSES`\n\nKey parameters:\n- `survey_id` -- the survey to retrieve responses from (required)\n- `status` -- filter by `completed`, `partial`, `overquota`, or `disqualified`\n- `page` / `per_page` -- pagination (default 50, max 1000)\n- `sort_order` -- `ASC` or `DESC` (sorted by `date_modified`)\n- `start_created_at` / `end_created_at` -- filter by creation date range (ISO 8601)\n- `start_modified_at` / `end_modified_at` -- filter by modification date range\n- `email` -- filter by respondent email\n- `first_name` / `last_name` -- filter by respondent name\n- `ip` -- filter by IP address\n- `total_time_min` / `total_time_max` / `total_time_units` -- filter by completion time\n\nExample prompt:\n> \"Get all completed responses for survey 123456789 from the last 30 days\"\n\n---\n\n### 6. Full Survey Lifecycle Workflow\n\nCombine tools for end-to-end survey management:\n\n1. **Create**: `SURVEY_MONKEY_CREATE_SURVEY` -- create the survey, store the `survey_id`\n2. **Distribute**: `SURVEY_MONKEY_GET_COLLECTORS` -- retrieve the collector link to share with respondents\n3. **Monitor**: `SURVEY_MONKEY_GET_SURVEY_DETAILS` -- check response counts and survey status\n4. **Collect**: `SURVEY_MONKEY_GET_RESPONSES` -- retrieve completed responses, filter by `status=completed`\n5. **Audit**: `SURVEY_MONKEY_GET_SURVEYS` -- browse and find surveys if `survey_id` is lost\n\nExample prompt:\n> \"Create a survey called 'Event Feedback', then show me how to distribute it\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Pagination required | `SURVEY_MONKEY_GET_COLLECTORS` and `SURVEY_MONKEY_GET_RESPONSES` require managing `page`/`per_page` for large surveys to avoid missing data |\n| Status filtering critical | `SURVEY_MONKEY_GET_RESPONSES` returns partial, overquota, and disqualified entries unless filtered -- use `status=completed` for reliable data |\n| No shareable link on create | `SURVEY_MONKEY_CREATE_SURVEY` does not create a distribution link -- use `SURVEY_MONKEY_GET_COLLECTORS` to get shareable URLs |\n| Survey ID storage | Losing track of `survey_id` forces reliance on `SURVEY_MONKEY_GET_SURVEYS` which is slower -- store IDs immediately after creation |\n| Question ID mapping | Question IDs and answer formats from responses must be carefully mapped; use `SURVEY_MONKEY_GET_SURVEY_DETAILS` to understand the structure |\n| Date format | Date filters use `YYYY-MM-DDTHH:MM:SS` format, not ISO 8601 with timezone |\n| Empty survey on create | New surveys start with one empty page and no questions -- further configuration is needed |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| Create survey | `SURVEY_MONKEY_CREATE_SURVEY` | `title`, `language`, `nickname` |\n| List surveys | `SURVEY_MONKEY_GET_SURVEYS` | `title`, `sort_by`, `include`, `page` |\n| Get survey details | `SURVEY_MONKEY_GET_SURVEY_DETAILS` | `survey_id` |\n| List collectors | `SURVEY_MONKEY_GET_COLLECTORS` | `survey_id`, `include`, `sort_by` |\n| Get responses | `SURVEY_MONKEY_GET_RESPONSES` | `survey_id`, `status`, `start_created_at` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/survey_monkey-automation/SKILL.md",
    "content": "---\nname: survey_monkey-automation\ndescription: \"Automate SurveyMonkey tasks via Rube MCP (Composio): surveys, responses, collectors, and survey analytics. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# SurveyMonkey Automation via Rube MCP\n\nAutomate SurveyMonkey operations through Composio's SurveyMonkey toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/survey_monkey](https://composio.dev/toolkits/survey_monkey)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active SurveyMonkey connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `survey_monkey`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `survey_monkey`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"surveys, responses, collectors, and survey analytics\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for SurveyMonkey\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available SurveyMonkey Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available SurveyMonkey tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute SurveyMonkey Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple SurveyMonkey operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the SurveyMonkey connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with SurveyMonkey-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `survey_monkey` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/survey_monkey](https://composio.dev/toolkits/survey_monkey)\n"
  },
  {
    "path": "composio-skills/svix-automation/SKILL.md",
    "content": "---\nname: svix-automation\ndescription: \"Automate Svix tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Svix Automation via Rube MCP\n\nAutomate Svix operations through Composio's Svix toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/svix](https://composio.dev/toolkits/svix)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Svix connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `svix`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `svix`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Svix operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Svix task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"svix\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Svix-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `svix` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/sympla-automation/SKILL.md",
    "content": "---\nname: sympla-automation\ndescription: \"Automate Sympla tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Sympla Automation via Rube MCP\n\nAutomate Sympla operations through Composio's Sympla toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/sympla](https://composio.dev/toolkits/sympla)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Sympla connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `sympla`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `sympla`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Sympla operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Sympla task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"sympla\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Sympla-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `sympla` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/synthflow-ai-automation/SKILL.md",
    "content": "---\nname: synthflow-ai-automation\ndescription: \"Automate Synthflow AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Synthflow AI Automation via Rube MCP\n\nAutomate Synthflow AI operations through Composio's Synthflow AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/synthflow_ai](https://composio.dev/toolkits/synthflow_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Synthflow AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `synthflow_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `synthflow_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Synthflow AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Synthflow AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"synthflow_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Synthflow AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `synthflow_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/taggun-automation/SKILL.md",
    "content": "---\nname: taggun-automation\ndescription: \"Automate Taggun tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Taggun Automation via Rube MCP\n\nAutomate Taggun operations through Composio's Taggun toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/taggun](https://composio.dev/toolkits/taggun)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Taggun connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `taggun`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `taggun`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Taggun operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Taggun task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"taggun\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Taggun-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `taggun` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/talenthr-automation/SKILL.md",
    "content": "---\nname: talenthr-automation\ndescription: \"Automate Talenthr tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Talenthr Automation via Rube MCP\n\nAutomate Talenthr operations through Composio's Talenthr toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/talenthr](https://composio.dev/toolkits/talenthr)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Talenthr connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `talenthr`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `talenthr`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Talenthr operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Talenthr task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"talenthr\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Talenthr-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `talenthr` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tally-automation/SKILL.md",
    "content": "---\nname: tally-automation\ndescription: \"Automate Tally tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tally Automation via Rube MCP\n\nAutomate Tally operations through Composio's Tally toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tally](https://composio.dev/toolkits/tally)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tally connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tally`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tally`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tally operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tally task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tally\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tally-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tally` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tapfiliate-automation/SKILL.md",
    "content": "---\nname: tapfiliate-automation\ndescription: \"Automate Tapfiliate tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tapfiliate Automation via Rube MCP\n\nAutomate Tapfiliate operations through Composio's Tapfiliate toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tapfiliate](https://composio.dev/toolkits/tapfiliate)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tapfiliate connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tapfiliate`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tapfiliate`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tapfiliate operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tapfiliate task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tapfiliate\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tapfiliate-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tapfiliate` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tapform-automation/SKILL.md",
    "content": "---\nname: tapform-automation\ndescription: \"Automate Tapform tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tapform Automation via Rube MCP\n\nAutomate Tapform operations through Composio's Tapform toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tapform](https://composio.dev/toolkits/tapform)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tapform connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tapform`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tapform`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tapform operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tapform task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tapform\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tapform-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tapform` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tavily-automation/SKILL.md",
    "content": "---\nname: tavily-automation\ndescription: \"Automate Tavily tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tavily Automation via Rube MCP\n\nAutomate Tavily operations through Composio's Tavily toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tavily](https://composio.dev/toolkits/tavily)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tavily connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tavily`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tavily`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tavily operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tavily task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tavily\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tavily-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tavily` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/taxjar-automation/SKILL.md",
    "content": "---\nname: taxjar-automation\ndescription: \"Automate Taxjar tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Taxjar Automation via Rube MCP\n\nAutomate Taxjar operations through Composio's Taxjar toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/taxjar](https://composio.dev/toolkits/taxjar)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Taxjar connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `taxjar`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `taxjar`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Taxjar operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Taxjar task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"taxjar\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Taxjar-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `taxjar` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/teamcamp-automation/SKILL.md",
    "content": "---\nname: teamcamp-automation\ndescription: \"Automate Teamcamp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Teamcamp Automation via Rube MCP\n\nAutomate Teamcamp operations through Composio's Teamcamp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/teamcamp](https://composio.dev/toolkits/teamcamp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Teamcamp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `teamcamp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `teamcamp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Teamcamp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Teamcamp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"teamcamp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Teamcamp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `teamcamp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/telnyx-automation/SKILL.md",
    "content": "---\nname: telnyx-automation\ndescription: \"Automate Telnyx tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Telnyx Automation via Rube MCP\n\nAutomate Telnyx operations through Composio's Telnyx toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/telnyx](https://composio.dev/toolkits/telnyx)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Telnyx connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `telnyx`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `telnyx`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Telnyx operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Telnyx task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"telnyx\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Telnyx-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `telnyx` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/teltel-automation/SKILL.md",
    "content": "---\nname: teltel-automation\ndescription: \"Automate Teltel tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Teltel Automation via Rube MCP\n\nAutomate Teltel operations through Composio's Teltel toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/teltel](https://composio.dev/toolkits/teltel)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Teltel connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `teltel`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `teltel`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Teltel operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Teltel task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"teltel\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Teltel-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `teltel` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/templated-automation/SKILL.md",
    "content": "---\nname: templated-automation\ndescription: \"Automate Templated tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Templated Automation via Rube MCP\n\nAutomate Templated operations through Composio's Templated toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/templated](https://composio.dev/toolkits/templated)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Templated connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `templated`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `templated`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Templated operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Templated task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"templated\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Templated-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `templated` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/test-app-automation/SKILL.md",
    "content": "---\nname: test-app-automation\ndescription: \"Automate Test App tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Test App Automation via Rube MCP\n\nAutomate Test App operations through Composio's Test App toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/test_app](https://composio.dev/toolkits/test_app)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Test App connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `test_app`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `test_app`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Test App operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Test App task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"test_app\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Test App-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `test_app` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/text-to-pdf-automation/SKILL.md",
    "content": "---\nname: text-to-pdf-automation\ndescription: \"Automate Text To PDF tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Text To PDF Automation via Rube MCP\n\nAutomate Text To PDF operations through Composio's Text To PDF toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/text_to_pdf](https://composio.dev/toolkits/text_to_pdf)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Text To PDF connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `text_to_pdf`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `text_to_pdf`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Text To PDF operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Text To PDF task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"text_to_pdf\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Text To PDF-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `text_to_pdf` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/textcortex-automation/SKILL.md",
    "content": "---\nname: textcortex-automation\ndescription: \"Automate Textcortex tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Textcortex Automation via Rube MCP\n\nAutomate Textcortex operations through Composio's Textcortex toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/textcortex](https://composio.dev/toolkits/textcortex)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Textcortex connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `textcortex`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `textcortex`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Textcortex operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Textcortex task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"textcortex\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Textcortex-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `textcortex` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/textit-automation/SKILL.md",
    "content": "---\nname: textit-automation\ndescription: \"Automate Textit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Textit Automation via Rube MCP\n\nAutomate Textit operations through Composio's Textit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/textit](https://composio.dev/toolkits/textit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Textit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `textit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `textit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Textit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Textit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"textit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Textit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `textit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/textrazor-automation/SKILL.md",
    "content": "---\nname: textrazor-automation\ndescription: \"Automate Textrazor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Textrazor Automation via Rube MCP\n\nAutomate Textrazor operations through Composio's Textrazor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/textrazor](https://composio.dev/toolkits/textrazor)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Textrazor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `textrazor`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `textrazor`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Textrazor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Textrazor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"textrazor\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Textrazor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `textrazor` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/thanks-io-automation/SKILL.md",
    "content": "---\nname: thanks-io-automation\ndescription: \"Automate Thanks IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Thanks IO Automation via Rube MCP\n\nAutomate Thanks IO operations through Composio's Thanks IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/thanks_io](https://composio.dev/toolkits/thanks_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Thanks IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `thanks_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `thanks_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Thanks IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Thanks IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"thanks_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Thanks IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `thanks_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/the-odds-api-automation/SKILL.md",
    "content": "---\nname: the-odds-api-automation\ndescription: \"Automate The Odds API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# The Odds API Automation via Rube MCP\n\nAutomate The Odds API operations through Composio's The Odds API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/the_odds_api](https://composio.dev/toolkits/the_odds_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active The Odds API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `the_odds_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `the_odds_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"The Odds API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific The Odds API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"the_odds_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with The Odds API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `the_odds_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ticketmaster-automation/SKILL.md",
    "content": "---\nname: ticketmaster-automation\ndescription: \"Automate Ticketmaster tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ticketmaster Automation via Rube MCP\n\nAutomate Ticketmaster operations through Composio's Ticketmaster toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ticketmaster](https://composio.dev/toolkits/ticketmaster)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ticketmaster connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ticketmaster`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ticketmaster`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ticketmaster operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ticketmaster task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ticketmaster\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ticketmaster-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ticketmaster` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ticktick-automation/SKILL.md",
    "content": "---\nname: ticktick-automation\ndescription: \"Automate Ticktick tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ticktick Automation via Rube MCP\n\nAutomate Ticktick operations through Composio's Ticktick toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ticktick](https://composio.dev/toolkits/ticktick)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ticktick connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ticktick`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ticktick`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ticktick operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ticktick task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ticktick\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ticktick-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ticktick` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/timecamp-automation/SKILL.md",
    "content": "---\nname: timecamp-automation\ndescription: \"Automate Timecamp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Timecamp Automation via Rube MCP\n\nAutomate Timecamp operations through Composio's Timecamp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/timecamp](https://composio.dev/toolkits/timecamp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Timecamp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `timecamp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `timecamp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Timecamp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Timecamp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"timecamp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Timecamp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `timecamp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/timekit-automation/SKILL.md",
    "content": "---\nname: timekit-automation\ndescription: \"Automate Timekit tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Timekit Automation via Rube MCP\n\nAutomate Timekit operations through Composio's Timekit toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/timekit](https://composio.dev/toolkits/timekit)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Timekit connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `timekit`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `timekit`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Timekit operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Timekit task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"timekit\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Timekit-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `timekit` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/timelinesai-automation/SKILL.md",
    "content": "---\nname: timelinesai-automation\ndescription: \"Automate Timelinesai tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Timelinesai Automation via Rube MCP\n\nAutomate Timelinesai operations through Composio's Timelinesai toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/timelinesai](https://composio.dev/toolkits/timelinesai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Timelinesai connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `timelinesai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `timelinesai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Timelinesai operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Timelinesai task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"timelinesai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Timelinesai-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `timelinesai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/timelink-automation/SKILL.md",
    "content": "---\nname: timelink-automation\ndescription: \"Automate Timelink tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Timelink Automation via Rube MCP\n\nAutomate Timelink operations through Composio's Timelink toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/timelink](https://composio.dev/toolkits/timelink)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Timelink connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `timelink`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `timelink`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Timelink operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Timelink task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"timelink\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Timelink-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `timelink` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/timely-automation/SKILL.md",
    "content": "---\nname: timely-automation\ndescription: \"Automate Timely tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Timely Automation via Rube MCP\n\nAutomate Timely operations through Composio's Timely toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/timely](https://composio.dev/toolkits/timely)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Timely connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `timely`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `timely`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Timely operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Timely task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"timely\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Timely-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `timely` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tinyurl-automation/SKILL.md",
    "content": "---\nname: tinyurl-automation\ndescription: \"Automate Tinyurl tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tinyurl Automation via Rube MCP\n\nAutomate Tinyurl operations through Composio's Tinyurl toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tinyurl](https://composio.dev/toolkits/tinyurl)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tinyurl connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tinyurl`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tinyurl`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tinyurl operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tinyurl task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tinyurl\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tinyurl-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tinyurl` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tisane-automation/SKILL.md",
    "content": "---\nname: tisane-automation\ndescription: \"Automate Tisane tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tisane Automation via Rube MCP\n\nAutomate Tisane operations through Composio's Tisane toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tisane](https://composio.dev/toolkits/tisane)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tisane connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tisane`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tisane`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tisane operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tisane task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tisane\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tisane-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tisane` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/toggl-automation/SKILL.md",
    "content": "---\nname: Toggl Automation\ndescription: \"Automate time tracking workflows in Toggl Track -- create time entries, manage projects, clients, tags, and workspaces through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Toggl Automation\n\nAutomate your Toggl Track time tracking operations directly from Claude Code. Log time, manage projects and clients, organize with tags, and control workspaces -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/toggl](https://composio.dev/toolkits/toggl)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Toggl Track account through the connection link provided\n3. Start automating your time tracking workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Create and Stop Time Entries\n\nLog time with project, task, and tag associations, or start/stop timers.\n\n**Tools:** `TOGGL_CREATE_TIME_ENTRY`, `TOGGL_PATCH_STOP_TIME_ENTRY`\n\n```\nStart a time entry in workspace 123456 for project 78910 tagged \"meeting\" and \"design\" with description \"Design review session\"\n```\n\nKey parameters for `TOGGL_CREATE_TIME_ENTRY`:\n- `workspace_id` (required) -- target workspace\n- `created_with` (required) -- client application name (e.g., `\"api_client\"`)\n- `start` (required) -- ISO 8601 timestamp\n- `stop` -- ISO 8601 end time; omit to leave the entry running\n- `duration` -- duration in seconds; omit for running entries\n- `project_id` -- associate with a project\n- `task_id` -- associate with a task\n- `tags` -- array of tag name strings (not IDs)\n- `description` -- description of the work\n- `billable` -- billable status\n\nKey parameters for `TOGGL_PATCH_STOP_TIME_ENTRY`:\n- `workspace_id` (required) and `time_entry_id` (required)\n\n### 2. Manage Projects\n\nCreate new projects and list existing ones with client details and pagination.\n\n**Tools:** `TOGGL_CREATE_PROJECT`, `TOGGL_GET_PROJECTS`, `TOGGL_GET_PROJECT_DETAILS`\n\n```\nCreate a private billable project called \"Q1 Marketing Campaign\" in workspace 123456 for client 78910\n```\n\nKey parameters for `TOGGL_CREATE_PROJECT`:\n- `workspace_id` (required) and `name` (required)\n- `client_id`, `billable`, `is_private`, `active`, `color`\n- `estimated_hours`, `rate`, `fixed_fee`, `currency` (premium features)\n\nKey parameters for `TOGGL_GET_PROJECTS`:\n- `workspace_id` (required)\n- `page` / `page_size` (1-200) for pagination\n- `since` / `until` -- Unix timestamps for modification filtering (last 3 months only)\n- `clients: true` to include full client details\n\n### 3. Manage Clients\n\nCreate and list clients within a workspace.\n\n**Tools:** `TOGGL_CREATE_CLIENT`, `TOGGL_GET_LIST_CLIENTS`\n\n```\nList all active clients in workspace 123456, then create a new client called \"Acme Corp\"\n```\n\n- `TOGGL_CREATE_CLIENT` requires `workspace_id` and `name`; accepts `notes`, `external_reference`\n- `TOGGL_GET_LIST_CLIENTS` requires `workspace_id`; supports `status` (`\"active\"`, `\"archived\"`, `\"both\"`) and `name` (case-insensitive search)\n\n### 4. Tags and Workspace Preferences\n\nRetrieve tags for categorization and check workspace settings.\n\n**Tools:** `TOGGL_GET_TAGS`, `TOGGL_GET_WORKSPACE_PREFERENCES`\n\n```\nShow me all tags in workspace 123456 and the workspace preferences\n```\n\n- `TOGGL_GET_TAGS` requires `workspace_id`; returns tag IDs and names\n- `TOGGL_GET_WORKSPACE_PREFERENCES` requires `workspace_id`; returns pricing plan and display settings\n\n### 5. Workspace Discovery\n\nList all workspaces the authenticated user belongs to.\n\n**Tool:** `TOGGL_GET_USER_WORKSPACES`\n\n```\nWhat Toggl workspaces do I have access to?\n```\n\n- No parameters required\n- Returns all workspaces with IDs, names, and metadata\n- Use this first to discover workspace IDs for other operations\n\n### 6. User Project Visibility\n\nList projects visible to the authenticated user.\n\n**Tool:** `TOGGL_GET_USER_PROJECTS`\n\n```\nShow me all projects I can see across my workspaces\n```\n\n- Returns projects the authenticated user has access to\n- Use alongside `TOGGL_GET_PROJECTS` for workspace-scoped views\n\n---\n\n## Known Pitfalls\n\n- **Tags use names, not IDs:** `TOGGL_CREATE_TIME_ENTRY` accepts tag names as strings in the `tags` array, unlike many APIs that use IDs. Use `TOGGL_GET_TAGS` to verify available tag names.\n- **`created_with` is required:** Every time entry must include `created_with` (e.g., `\"api_client\"`). Missing this field causes silent failures.\n- **Duration is in seconds:** The `duration` parameter on time entries is in seconds, not hours. 1 hour = 3600 seconds.\n- **`since` timestamp restriction:** The `since` filter on `TOGGL_GET_PROJECTS` only allows timestamps within the last 3 months. Older queries will be rejected.\n- **Premium features gated:** Custom colors, templates, fixed fees, and hourly rates on projects require a premium Toggl plan. Non-premium accounts will get errors when using these fields.\n- **Workspace ID required everywhere:** Nearly all Toggl tools require `workspace_id`. Always call `TOGGL_GET_USER_WORKSPACES` first to resolve it.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `TOGGL_CREATE_TIME_ENTRY` | Create a time entry or running timer (requires `workspace_id`, `created_with`, `start`) |\n| `TOGGL_PATCH_STOP_TIME_ENTRY` | Stop a running time entry (requires `workspace_id`, `time_entry_id`) |\n| `TOGGL_GET_PROJECTS` | List projects in a workspace with pagination |\n| `TOGGL_GET_PROJECT_DETAILS` | Get details for a specific project |\n| `TOGGL_CREATE_PROJECT` | Create a new project (requires `workspace_id`, `name`) |\n| `TOGGL_GET_LIST_CLIENTS` | List clients with status/name filters (requires `workspace_id`) |\n| `TOGGL_CREATE_CLIENT` | Create a new client (requires `workspace_id`, `name`) |\n| `TOGGL_GET_TAGS` | List all tags in a workspace (requires `workspace_id`) |\n| `TOGGL_GET_WORKSPACE_PREFERENCES` | Get workspace settings (requires `workspace_id`) |\n| `TOGGL_GET_USER_WORKSPACES` | List all workspaces for the authenticated user |\n| `TOGGL_GET_USER_PROJECTS` | List projects visible to the authenticated user |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/token-metrics-automation/SKILL.md",
    "content": "---\nname: token-metrics-automation\ndescription: \"Automate Token Metrics tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Token Metrics Automation via Rube MCP\n\nAutomate Token Metrics operations through Composio's Token Metrics toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/token_metrics](https://composio.dev/toolkits/token_metrics)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Token Metrics connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `token_metrics`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `token_metrics`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Token Metrics operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Token Metrics task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"token_metrics\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Token Metrics-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `token_metrics` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tomba-automation/SKILL.md",
    "content": "---\nname: tomba-automation\ndescription: \"Automate Tomba tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tomba Automation via Rube MCP\n\nAutomate Tomba operations through Composio's Tomba toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tomba](https://composio.dev/toolkits/tomba)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tomba connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tomba`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tomba`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tomba operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tomba task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tomba\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tomba-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tomba` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tomtom-automation/SKILL.md",
    "content": "---\nname: tomtom-automation\ndescription: \"Automate Tomtom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tomtom Automation via Rube MCP\n\nAutomate Tomtom operations through Composio's Tomtom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tomtom](https://composio.dev/toolkits/tomtom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tomtom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tomtom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tomtom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tomtom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tomtom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tomtom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tomtom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tomtom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/toneden-automation/SKILL.md",
    "content": "---\nname: toneden-automation\ndescription: \"Automate Toneden tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Toneden Automation via Rube MCP\n\nAutomate Toneden operations through Composio's Toneden toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/toneden](https://composio.dev/toolkits/toneden)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Toneden connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `toneden`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `toneden`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Toneden operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Toneden task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"toneden\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Toneden-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `toneden` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tpscheck-automation/SKILL.md",
    "content": "---\nname: tpscheck-automation\ndescription: \"Automate Tpscheck tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Tpscheck Automation via Rube MCP\n\nAutomate Tpscheck operations through Composio's Tpscheck toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tpscheck](https://composio.dev/toolkits/tpscheck)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Tpscheck connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tpscheck`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tpscheck`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Tpscheck operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Tpscheck task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tpscheck\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Tpscheck-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tpscheck` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/triggercmd-automation/SKILL.md",
    "content": "---\nname: triggercmd-automation\ndescription: \"Automate Triggercmd tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Triggercmd Automation via Rube MCP\n\nAutomate Triggercmd operations through Composio's Triggercmd toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/triggercmd](https://composio.dev/toolkits/triggercmd)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Triggercmd connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `triggercmd`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `triggercmd`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Triggercmd operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Triggercmd task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"triggercmd\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Triggercmd-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `triggercmd` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/tripadvisor-content-api-automation/SKILL.md",
    "content": "---\nname: tripadvisor-content-api-automation\ndescription: \"Automate TripAdvisor tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# TripAdvisor Automation via Rube MCP\n\nAutomate TripAdvisor operations through Composio's TripAdvisor toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/tripadvisor_content_api](https://composio.dev/toolkits/tripadvisor_content_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active TripAdvisor connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `tripadvisor_content_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `tripadvisor_content_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"TripAdvisor operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific TripAdvisor task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"tripadvisor_content_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with TripAdvisor-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `tripadvisor_content_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/turbot-pipes-automation/SKILL.md",
    "content": "---\nname: turbot-pipes-automation\ndescription: \"Automate Turbot Pipes tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Turbot Pipes Automation via Rube MCP\n\nAutomate Turbot Pipes operations through Composio's Turbot Pipes toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/turbot_pipes](https://composio.dev/toolkits/turbot_pipes)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Turbot Pipes connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `turbot_pipes`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `turbot_pipes`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Turbot Pipes operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Turbot Pipes task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"turbot_pipes\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Turbot Pipes-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `turbot_pipes` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/turso-automation/SKILL.md",
    "content": "---\nname: turso-automation\ndescription: \"Automate Turso tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Turso Automation via Rube MCP\n\nAutomate Turso operations through Composio's Turso toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/turso](https://composio.dev/toolkits/turso)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Turso connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `turso`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `turso`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Turso operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Turso task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"turso\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Turso-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `turso` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/twelve-data-automation/SKILL.md",
    "content": "---\nname: twelve-data-automation\ndescription: \"Automate Twelve Data tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Twelve Data Automation via Rube MCP\n\nAutomate Twelve Data operations through Composio's Twelve Data toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/twelve_data](https://composio.dev/toolkits/twelve_data)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Twelve Data connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `twelve_data`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `twelve_data`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Twelve Data operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Twelve Data task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"twelve_data\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Twelve Data-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `twelve_data` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/twitch-automation/SKILL.md",
    "content": "---\nname: twitch-automation\ndescription: \"Automate Twitch tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Twitch Automation via Rube MCP\n\nAutomate Twitch operations through Composio's Twitch toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/twitch](https://composio.dev/toolkits/twitch)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Twitch connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `twitch`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `twitch`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Twitch operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Twitch task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"twitch\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Twitch-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `twitch` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/twocaptcha-automation/SKILL.md",
    "content": "---\nname: twocaptcha-automation\ndescription: \"Automate Twocaptcha tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Twocaptcha Automation via Rube MCP\n\nAutomate Twocaptcha operations through Composio's Twocaptcha toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/twocaptcha](https://composio.dev/toolkits/twocaptcha)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Twocaptcha connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `twocaptcha`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `twocaptcha`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Twocaptcha operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Twocaptcha task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"twocaptcha\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Twocaptcha-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `twocaptcha` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/typefully-automation/SKILL.md",
    "content": "---\nname: typefully-automation\ndescription: \"Automate Typefully tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Typefully Automation via Rube MCP\n\nAutomate Typefully operations through Composio's Typefully toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/typefully](https://composio.dev/toolkits/typefully)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Typefully connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `typefully`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `typefully`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Typefully operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Typefully task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"typefully\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Typefully-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `typefully` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/typless-automation/SKILL.md",
    "content": "---\nname: typless-automation\ndescription: \"Automate Typless tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Typless Automation via Rube MCP\n\nAutomate Typless operations through Composio's Typless toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/typless](https://composio.dev/toolkits/typless)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Typless connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `typless`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `typless`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Typless operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Typless task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"typless\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Typless-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `typless` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/u301-automation/SKILL.md",
    "content": "---\nname: u301-automation\ndescription: \"Automate U301 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# U301 Automation via Rube MCP\n\nAutomate U301 operations through Composio's U301 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/u301](https://composio.dev/toolkits/u301)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active U301 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `u301`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `u301`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"U301 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific U301 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"u301\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with U301-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `u301` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/unione-automation/SKILL.md",
    "content": "---\nname: unione-automation\ndescription: \"Automate Unione tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Unione Automation via Rube MCP\n\nAutomate Unione operations through Composio's Unione toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/unione](https://composio.dev/toolkits/unione)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Unione connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `unione`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `unione`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Unione operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Unione task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"unione\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Unione-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `unione` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/updown-io-automation/SKILL.md",
    "content": "---\nname: updown-io-automation\ndescription: \"Automate Updown IO tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Updown IO Automation via Rube MCP\n\nAutomate Updown IO operations through Composio's Updown IO toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/updown_io](https://composio.dev/toolkits/updown_io)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Updown IO connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `updown_io`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `updown_io`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Updown IO operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Updown IO task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"updown_io\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Updown IO-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `updown_io` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/uploadcare-automation/SKILL.md",
    "content": "---\nname: Uploadcare Automation\ndescription: \"Automate Uploadcare file management including listing, storing, inspecting, downloading, and organizing file groups through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Uploadcare Automation\n\nAutomate Uploadcare file handling workflows -- list project files, permanently store uploads, retrieve file metadata, get download URLs, and manage file groups -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/uploadcare](https://composio.dev/toolkits/uploadcare)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Uploadcare account when prompted (API key auth via Composio)\n3. Start issuing natural language commands for Uploadcare automation\n\n---\n\n## Core Workflows\n\n### 1. List Project Files\n\nBrowse uploaded files in your Uploadcare project with filtering, sorting, and pagination.\n\n**Tool:** `UPLOADCARE_LIST_FILES`\n\nKey parameters:\n- `stored` -- filter by storage status: `\"true\"` for stored, `\"false\"` for unstored\n- `removed` -- filter by removal status: `\"true\"` for removed, `\"false\"` for active\n- `ordering` -- sort by `datetime_uploaded` (ascending) or `-datetime_uploaded` (descending)\n- `limit` -- files per page, 1-1000 (default 100)\n- `offset` -- zero-based pagination offset\n- `from_date` -- ISO 8601 timestamp to filter files uploaded after this date\n- `to_date` -- ISO 8601 timestamp to filter files uploaded before this date\n- `include` -- set to `\"total\"` to include total file count in response\n\nExample prompt:\n> \"List the 50 most recently uploaded stored files in my Uploadcare project\"\n\n---\n\n### 2. Store a File Permanently\n\nMark an uploaded file as permanently stored. By default, Uploadcare files are temporary and will be deleted after 24 hours unless stored.\n\n**Tool:** `UPLOADCARE_STORE_FILE`\n\nKey parameters:\n- `uuid` -- UUID of the file to store (required); must be in `8-4-4-4-12` hex format (e.g., `3e55317b-23d1-4f35-9b4c-b9accb7b53f4`)\n\n> Always store files after upload to prevent automatic deletion.\n\nExample prompt:\n> \"Permanently store the file with UUID 3e55317b-23d1-4f35-9b4c-b9accb7b53f4\"\n\n---\n\n### 3. Get File Metadata\n\nRetrieve detailed information about a specific file including size, MIME type, CDN URL, image dimensions, and more.\n\n**Tool:** `UPLOADCARE_GET_FILE_INFO`\n\nKey parameters:\n- `uuid` -- the UUID of the file to inspect (required); format: `8-4-4-4-12` hex\n\nReturns: filename, size, MIME type, CDN URL, upload date, storage status, image info (dimensions, color mode), and more.\n\nExample prompt:\n> \"Get the metadata and dimensions for file 3e0923f2-e05a-4b37-9f0d-343b981c9d70\"\n\n---\n\n### 4. Get a Temporary Download URL\n\nRetrieve a temporary direct download link for a specific file.\n\n**Tool:** `UPLOADCARE_GET_FILE_DOWNLOAD_URL`\n\nKey parameters:\n- `file_id` -- the unique file identifier (required)\n\nReturns a time-limited URL that can be used for direct file download.\n\nExample prompt:\n> \"Get a download link for file 3e0923f2-e05a-4b37-9f0d-343b981c9d70\"\n\n---\n\n### 5. Browse File Groups\n\nList file groups in your project. Groups are collections of files uploaded together.\n\n**Tool:** `UPLOADCARE_LIST_GROUPS`\n\nKey parameters:\n- `limit` -- groups per page, 1-1000 (default 20)\n- `offset` -- zero-based pagination offset (default 0)\n- `ordering` -- sort by `datetime_created` (ascending) or `-datetime_created` (descending)\n\nExample prompt:\n> \"List my 10 most recent file groups\"\n\n---\n\n### 6. File Lifecycle Workflow\n\nCombine tools for end-to-end file management:\n\n1. **Upload**: Files are uploaded via Uploadcare's upload API or widget (outside this toolkit)\n2. **Store**: `UPLOADCARE_STORE_FILE` -- mark files as permanent to prevent auto-deletion\n3. **Inspect**: `UPLOADCARE_GET_FILE_INFO` -- verify metadata, check dimensions and MIME type\n4. **Share**: `UPLOADCARE_GET_FILE_DOWNLOAD_URL` -- generate a temporary download link\n5. **Browse**: `UPLOADCARE_LIST_FILES` -- audit all files with status and date filters\n6. **Groups**: `UPLOADCARE_LIST_GROUPS` -- review batch uploads\n\nExample prompt:\n> \"Store file abc-123, then get its metadata and a download link\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Auto-deletion of unstored files | Uploaded files are temporary by default and deleted after 24 hours -- always call `UPLOADCARE_STORE_FILE` to persist them |\n| UUID format strict | File UUIDs must be in exact `8-4-4-4-12` hex format (e.g., `3e55317b-23d1-4f35-9b4c-b9accb7b53f4`); invalid formats will be rejected |\n| Filter values are strings | The `stored` and `removed` parameters accept string values `\"true\"` or `\"false\"`, not booleans |\n| Temporary download URLs | URLs from `UPLOADCARE_GET_FILE_DOWNLOAD_URL` are time-limited and will expire |\n| Pagination is offset-based | Use `offset` + `limit` for pagination; there are no cursor-based pagination tokens |\n| No upload tool | File uploads happen through Uploadcare's upload API or widget, not through this toolkit -- these tools manage already-uploaded files |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| List files | `UPLOADCARE_LIST_FILES` | `stored`, `ordering`, `limit`, `offset` |\n| Store file | `UPLOADCARE_STORE_FILE` | `uuid` |\n| Get file info | `UPLOADCARE_GET_FILE_INFO` | `uuid` |\n| Get download URL | `UPLOADCARE_GET_FILE_DOWNLOAD_URL` | `file_id` |\n| List groups | `UPLOADCARE_LIST_GROUPS` | `limit`, `offset`, `ordering` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/uptimerobot-automation/SKILL.md",
    "content": "---\nname: uptimerobot-automation\ndescription: \"Automate Uptimerobot tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Uptimerobot Automation via Rube MCP\n\nAutomate Uptimerobot operations through Composio's Uptimerobot toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/uptimerobot](https://composio.dev/toolkits/uptimerobot)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Uptimerobot connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `uptimerobot`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `uptimerobot`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Uptimerobot operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Uptimerobot task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"uptimerobot\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Uptimerobot-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `uptimerobot` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/userlist-automation/SKILL.md",
    "content": "---\nname: userlist-automation\ndescription: \"Automate Userlist tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Userlist Automation via Rube MCP\n\nAutomate Userlist operations through Composio's Userlist toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/userlist](https://composio.dev/toolkits/userlist)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Userlist connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `userlist`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `userlist`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Userlist operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Userlist task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"userlist\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Userlist-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `userlist` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/v0-automation/SKILL.md",
    "content": "---\nname: v0-automation\ndescription: \"Automate V0 tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# V0 Automation via Rube MCP\n\nAutomate V0 operations through Composio's V0 toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/v0](https://composio.dev/toolkits/v0)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active V0 connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `v0`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `v0`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"V0 operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific V0 task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"v0\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with V0-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `v0` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/venly-automation/SKILL.md",
    "content": "---\nname: venly-automation\ndescription: \"Automate Venly tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Venly Automation via Rube MCP\n\nAutomate Venly operations through Composio's Venly toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/venly](https://composio.dev/toolkits/venly)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Venly connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `venly`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `venly`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Venly operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Venly task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"venly\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Venly-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `venly` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/veo-automation/SKILL.md",
    "content": "---\nname: veo-automation\ndescription: \"Automate Veo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Veo Automation via Rube MCP\n\nAutomate Veo operations through Composio's Veo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/veo](https://composio.dev/toolkits/veo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Veo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `veo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `veo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Veo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Veo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"veo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Veo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `veo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/verifiedemail-automation/SKILL.md",
    "content": "---\nname: verifiedemail-automation\ndescription: \"Automate Verifiedemail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Verifiedemail Automation via Rube MCP\n\nAutomate Verifiedemail operations through Composio's Verifiedemail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/verifiedemail](https://composio.dev/toolkits/verifiedemail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Verifiedemail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `verifiedemail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `verifiedemail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Verifiedemail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Verifiedemail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"verifiedemail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Verifiedemail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `verifiedemail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/veriphone-automation/SKILL.md",
    "content": "---\nname: veriphone-automation\ndescription: \"Automate Veriphone tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Veriphone Automation via Rube MCP\n\nAutomate Veriphone operations through Composio's Veriphone toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/veriphone](https://composio.dev/toolkits/veriphone)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Veriphone connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `veriphone`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `veriphone`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Veriphone operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Veriphone task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"veriphone\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Veriphone-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `veriphone` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/vero-automation/SKILL.md",
    "content": "---\nname: vero-automation\ndescription: \"Automate Vero tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Vero Automation via Rube MCP\n\nAutomate Vero operations through Composio's Vero toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/vero](https://composio.dev/toolkits/vero)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Vero connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `vero`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `vero`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Vero operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Vero task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"vero\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Vero-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `vero` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/vestaboard-automation/SKILL.md",
    "content": "---\nname: vestaboard-automation\ndescription: \"Automate Vestaboard tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Vestaboard Automation via Rube MCP\n\nAutomate Vestaboard operations through Composio's Vestaboard toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/vestaboard](https://composio.dev/toolkits/vestaboard)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Vestaboard connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `vestaboard`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `vestaboard`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Vestaboard operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Vestaboard task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"vestaboard\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Vestaboard-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `vestaboard` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/virustotal-automation/SKILL.md",
    "content": "---\nname: virustotal-automation\ndescription: \"Automate Virustotal tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Virustotal Automation via Rube MCP\n\nAutomate Virustotal operations through Composio's Virustotal toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/virustotal](https://composio.dev/toolkits/virustotal)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Virustotal connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `virustotal`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `virustotal`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Virustotal operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Virustotal task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"virustotal\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Virustotal-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `virustotal` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/visme-automation/SKILL.md",
    "content": "---\nname: visme-automation\ndescription: \"Automate Visme tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Visme Automation via Rube MCP\n\nAutomate Visme operations through Composio's Visme toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/visme](https://composio.dev/toolkits/visme)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Visme connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `visme`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `visme`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Visme operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Visme task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"visme\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Visme-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `visme` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/waboxapp-automation/SKILL.md",
    "content": "---\nname: waboxapp-automation\ndescription: \"Automate Waboxapp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Waboxapp Automation via Rube MCP\n\nAutomate Waboxapp operations through Composio's Waboxapp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/waboxapp](https://composio.dev/toolkits/waboxapp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Waboxapp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `waboxapp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `waboxapp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Waboxapp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Waboxapp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"waboxapp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Waboxapp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `waboxapp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wachete-automation/SKILL.md",
    "content": "---\nname: wachete-automation\ndescription: \"Automate Wachete tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wachete Automation via Rube MCP\n\nAutomate Wachete operations through Composio's Wachete toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wachete](https://composio.dev/toolkits/wachete)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wachete connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wachete`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wachete`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wachete operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wachete task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wachete\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wachete-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wachete` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/waiverfile-automation/SKILL.md",
    "content": "---\nname: waiverfile-automation\ndescription: \"Automate Waiverfile tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Waiverfile Automation via Rube MCP\n\nAutomate Waiverfile operations through Composio's Waiverfile toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/waiverfile](https://composio.dev/toolkits/waiverfile)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Waiverfile connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `waiverfile`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `waiverfile`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Waiverfile operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Waiverfile task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"waiverfile\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Waiverfile-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `waiverfile` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wakatime-automation/SKILL.md",
    "content": "---\nname: wakatime-automation\ndescription: \"Automate Wakatime tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wakatime Automation via Rube MCP\n\nAutomate Wakatime operations through Composio's Wakatime toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wakatime](https://composio.dev/toolkits/wakatime)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wakatime connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wakatime`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wakatime`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wakatime operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wakatime task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wakatime\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wakatime-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wakatime` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wati-automation/SKILL.md",
    "content": "---\nname: wati-automation\ndescription: \"Automate Wati tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wati Automation via Rube MCP\n\nAutomate Wati operations through Composio's Wati toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wati](https://composio.dev/toolkits/wati)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wati connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wati`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wati`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wati operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wati task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wati\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wati-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wati` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wave-accounting-automation/SKILL.md",
    "content": "---\nname: Wave Accounting Automation\ndescription: \"Wave Accounting toolkit is not currently available as a native integration. No Wave-specific tools were found in the Composio platform. This skill is a placeholder pending future integration.\"\ncategory: accounting\nrequires:\n  mcp:\n    - rube\n---\n\n# Wave Accounting Automation\n\n> **Note:** The Wave Accounting toolkit (`wave_accounting`) does not currently have native tools available in the Composio platform. Searches for Wave Accounting-specific tools return results from other accounting/invoicing platforms (Stripe, Zoho Invoice) instead.\n\n**Toolkit docs:** [composio.dev/toolkits/wave_accounting](https://composio.dev/toolkits/wave_accounting)\n\n---\n\n## Status\n\nThis integration is **not yet available** with native Wave Accounting tools. When Wave Accounting tools become available in Composio, this skill file will be updated with real tool slugs, workflows, and pitfalls.\n\nFor accounting and invoicing automation needs, consider these alternatives that are available today:\n- **Stripe** -- Payment processing, invoicing, and subscription management\n- **Zoho Invoice** -- Invoice creation, payment tracking, and contact management\n- **QuickBooks** -- Full accounting suite with invoicing and expense tracking\n- **FreshBooks** -- Cloud accounting with time tracking and invoicing\n\n---\n\n## Setup\n\n1. Add the Composio MCP server to your client configuration:\n   ```\n   https://rube.app/mcp\n   ```\n2. Check back for Wave Accounting integration availability.\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wave_accounting-automation/SKILL.md",
    "content": "---\nname: wave_accounting-automation\ndescription: \"Automate Wave Accounting tasks via Rube MCP (Composio): invoices, customers, payments, and small business accounting. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wave Accounting Automation via Rube MCP\n\nAutomate Wave Accounting operations through Composio's Wave Accounting toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wave_accounting](https://composio.dev/toolkits/wave_accounting)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wave Accounting connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wave_accounting`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wave_accounting`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"invoices, customers, payments, and small business accounting\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Wave Accounting\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Wave Accounting Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Wave Accounting tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Wave Accounting Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Wave Accounting operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Wave Accounting connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wave Accounting-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wave_accounting` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/wave_accounting](https://composio.dev/toolkits/wave_accounting)\n"
  },
  {
    "path": "composio-skills/weathermap-automation/SKILL.md",
    "content": "---\nname: weathermap-automation\ndescription: \"Automate Weathermap tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Weathermap Automation via Rube MCP\n\nAutomate Weathermap operations through Composio's Weathermap toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/weathermap](https://composio.dev/toolkits/weathermap)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Weathermap connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `weathermap`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `weathermap`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Weathermap operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Weathermap task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"weathermap\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Weathermap-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `weathermap` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/webex-automation/SKILL.md",
    "content": "---\nname: Webex Automation\ndescription: \"Automate Cisco Webex messaging, rooms, teams, webhooks, and people management through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Webex Automation\n\nAutomate Cisco Webex collaboration workflows -- send messages, manage rooms and teams, configure webhooks, and look up people -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/webex](https://composio.dev/toolkits/webex)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Webex account when prompted (OAuth flow via Composio)\n3. Start issuing natural language commands for Webex automation\n\n---\n\n## Core Workflows\n\n### 1. Send a Message to a Room or Person\n\nPost plain text, markdown, file attachments, or Adaptive Cards to any Webex room or directly to a person.\n\n**Tool:** `WEBEX_MESSAGING_CREATE_MESSAGE`\n\nKey parameters:\n- `roomId` -- target room ID (use `WEBEX_MESSAGING_LIST_ROOMS` to find it)\n- `toPersonEmail` -- send a private 1:1 message instead (mutually exclusive with `roomId`)\n- `text` -- plain text content (max 7439 bytes)\n- `markdown` -- markdown-formatted content (takes precedence over `text`)\n- `files` -- list of public URLs for file attachments (one file per message)\n- `attachments` -- Adaptive Card JSON (one card per message)\n- `parentId` -- reply to a specific message as a threaded response\n\nExample prompt:\n> \"Send a markdown message to room Y2lz... saying **Deploy completed** with a link to the release notes\"\n\n---\n\n### 2. List and Discover Rooms\n\nBrowse all rooms you belong to, filtered by type, team, or sorted by activity.\n\n**Tool:** `WEBEX_MESSAGING_LIST_ROOMS`\n\nKey parameters:\n- `type` -- filter by `direct` (1:1) or `group`\n- `teamId` -- limit to rooms in a specific team\n- `sortBy` -- sort by `id`, `lastactivity`, or `created`\n- `max` -- limit results (1-1000, default 100)\n\nFollow-up with `WEBEX_MESSAGING_GET_ROOM_DETAILS` to get full metadata for a specific room including title, type, lock status, creator, and timestamps.\n\nExample prompt:\n> \"List my 10 most recently active group rooms in Webex\"\n\n---\n\n### 3. Manage Webhooks for Event-Driven Automation\n\nCreate webhooks to receive real-time HTTP POST notifications when Webex resources change.\n\n**Tool:** `WEBEX_WEBHOOKS_CREATE_WEBHOOK`\n\nKey parameters:\n- `name` -- human-friendly webhook name (required)\n- `targetUrl` -- URL that receives POST notifications (required)\n- `resource` -- what to monitor: `messages`, `rooms`, `memberships`, `meetings`, `recordings`, `meetingParticipants`, `telephony_calls`, etc. (required)\n- `event` -- trigger type: `created`, `updated`, `deleted`, `started`, `ended`, `joined`, `left` (required)\n- `filter` -- scope notifications (e.g., `roomId=<id>` or `hostEmail=<email>`)\n- `secret` -- optional HMAC secret for payload signature verification\n- `ownedBy` -- `creator` for personal or `org` for organization-wide webhooks\n\nSupporting tools:\n- `WEBEX_LIST_WEBHOOKS` -- list all registered webhooks with optional `max` and `ownedBy` filters\n- `WEBEX_WEBHOOKS_GET_WEBHOOK` -- inspect a specific webhook by `webhookId`\n\nExample prompt:\n> \"Create a webhook called 'New Messages' that POSTs to https://my-app.com/hook whenever a message is created in room Y2lz...\"\n\n---\n\n### 4. Manage Team Memberships\n\nAdd people to Webex teams and optionally grant moderator privileges.\n\n**Tool:** `WEBEX_MESSAGING_CREATE_TEAM_MEMBERSHIP`\n\nKey parameters:\n- `teamId` -- the team to add the person to (required)\n- `personEmail` -- email of the person to add\n- `personId` -- Webex person ID (alternative to email)\n- `isModerator` -- set to `true` for moderator access (default `false`)\n\nUse `WEBEX_LIST_TEAMS` to discover available teams first.\n\nExample prompt:\n> \"Add alice@example.com as a moderator to team Y2lz...\"\n\n---\n\n### 5. Audit Room Memberships\n\nCheck who is in a room, verify a specific person's membership, or list memberships across teams.\n\n**Tool:** `WEBEX_MESSAGING_LIST_MEMBERSHIPS`\n\nKey parameters:\n- `roomId` -- list all members of a specific room\n- `personEmail` -- check if a person is a member (requires `roomId`)\n- `personId` -- check by Webex person ID (requires `roomId`)\n- `teamId` -- filter by team association\n- `max` -- limit results\n\nExample prompt:\n> \"List all members of room Y2lz... and tell me who the moderators are\"\n\n---\n\n### 6. Search and Look Up People\n\nLook up people in your Webex organization by email, display name, or ID.\n\n**Tool:** `WEBEX_PEOPLE_LIST_PEOPLE`\n\nUse to resolve names to person IDs before sending direct messages or adding team members.\n\nExample prompt:\n> \"Find the Webex person ID for bob@company.com\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Webhook auto-disable | Target URL must respond with HTTP 2xx; 100 failures in 5 minutes disables the webhook automatically |\n| Message size limit | Both `text` and `markdown` have a 7439-byte maximum |\n| One file per message | The `files` array accepts a list but only one attachment is actually supported per message |\n| One card per message | Only one Adaptive Card attachment is supported per message |\n| Mutually exclusive targets | `roomId` and `toPersonEmail`/`toPersonId` cannot be used together when sending messages |\n| Room update requires title | `WEBEX_UPDATE_ROOM` always requires the `title` parameter, even when only changing lock status or team |\n| orgPublicSpaces conflicts | Cannot combine `orgPublicSpaces` with `teamId`, `type`, or `sortBy` when listing rooms |\n| Webhook read scope | Creating a webhook requires `read` scope on the monitored resource type |\n| Membership filter requires roomId | `personEmail` and `personId` filters in list memberships require `roomId` unless you are a Compliance Officer |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| Send message | `WEBEX_MESSAGING_CREATE_MESSAGE` | `roomId`, `text`/`markdown`, `toPersonEmail` |\n| List rooms | `WEBEX_MESSAGING_LIST_ROOMS` | `type`, `sortBy`, `max` |\n| Get room details | `WEBEX_MESSAGING_GET_ROOM_DETAILS` | `roomId` |\n| Update room | `WEBEX_UPDATE_ROOM` | `roomId`, `title` |\n| Delete message | `WEBEX_MESSAGING_DELETE_MESSAGE` | `messageId` |\n| Get message details | `WEBEX_MESSAGING_GET_MESSAGE_DETAILS` | `messageId` |\n| Create webhook | `WEBEX_WEBHOOKS_CREATE_WEBHOOK` | `name`, `targetUrl`, `resource`, `event` |\n| List webhooks | `WEBEX_LIST_WEBHOOKS` | `max`, `ownedBy` |\n| Get webhook | `WEBEX_WEBHOOKS_GET_WEBHOOK` | `webhookId` |\n| Add team member | `WEBEX_MESSAGING_CREATE_TEAM_MEMBERSHIP` | `teamId`, `personEmail`, `isModerator` |\n| List memberships | `WEBEX_MESSAGING_LIST_MEMBERSHIPS` | `roomId`, `personEmail`, `max` |\n| List people | `WEBEX_PEOPLE_LIST_PEOPLE` | email, displayName, ID filters |\n| List teams | `WEBEX_LIST_TEAMS` | `max` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/webscraping-ai-automation/SKILL.md",
    "content": "---\nname: webscraping-ai-automation\ndescription: \"Automate Webscraping AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Webscraping AI Automation via Rube MCP\n\nAutomate Webscraping AI operations through Composio's Webscraping AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/webscraping_ai](https://composio.dev/toolkits/webscraping_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Webscraping AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `webscraping_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `webscraping_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Webscraping AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Webscraping AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"webscraping_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Webscraping AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `webscraping_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/webvizio-automation/SKILL.md",
    "content": "---\nname: webvizio-automation\ndescription: \"Automate Webvizio tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Webvizio Automation via Rube MCP\n\nAutomate Webvizio operations through Composio's Webvizio toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/webvizio](https://composio.dev/toolkits/webvizio)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Webvizio connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `webvizio`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `webvizio`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Webvizio operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Webvizio task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"webvizio\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Webvizio-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `webvizio` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/whautomate-automation/SKILL.md",
    "content": "---\nname: whautomate-automation\ndescription: \"Automate Whautomate tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Whautomate Automation via Rube MCP\n\nAutomate Whautomate operations through Composio's Whautomate toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/whautomate](https://composio.dev/toolkits/whautomate)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Whautomate connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `whautomate`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `whautomate`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Whautomate operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Whautomate task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"whautomate\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Whautomate-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `whautomate` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/winston-ai-automation/SKILL.md",
    "content": "---\nname: winston-ai-automation\ndescription: \"Automate Winston AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Winston AI Automation via Rube MCP\n\nAutomate Winston AI operations through Composio's Winston AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/winston_ai](https://composio.dev/toolkits/winston_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Winston AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `winston_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `winston_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Winston AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Winston AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"winston_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Winston AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `winston_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wit-ai-automation/SKILL.md",
    "content": "---\nname: wit-ai-automation\ndescription: \"Automate Wit AI tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wit AI Automation via Rube MCP\n\nAutomate Wit AI operations through Composio's Wit AI toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wit_ai](https://composio.dev/toolkits/wit_ai)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wit AI connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wit_ai`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wit_ai`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wit AI operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wit AI task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wit_ai\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wit AI-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wit_ai` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wiz-automation/SKILL.md",
    "content": "---\nname: wiz-automation\ndescription: \"Automate Wiz tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wiz Automation via Rube MCP\n\nAutomate Wiz operations through Composio's Wiz toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wiz](https://composio.dev/toolkits/wiz)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wiz connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wiz`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wiz`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wiz operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wiz task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wiz\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wiz-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wiz` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/wolfram-alpha-api-automation/SKILL.md",
    "content": "---\nname: wolfram-alpha-api-automation\ndescription: \"Automate Wolfram Alpha API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Wolfram Alpha API Automation via Rube MCP\n\nAutomate Wolfram Alpha API operations through Composio's Wolfram Alpha API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/wolfram_alpha_api](https://composio.dev/toolkits/wolfram_alpha_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Wolfram Alpha API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `wolfram_alpha_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `wolfram_alpha_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Wolfram Alpha API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Wolfram Alpha API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"wolfram_alpha_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Wolfram Alpha API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `wolfram_alpha_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/woodpecker-co-automation/SKILL.md",
    "content": "---\nname: woodpecker-co-automation\ndescription: \"Automate Woodpecker co tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Woodpecker co Automation via Rube MCP\n\nAutomate Woodpecker co operations through Composio's Woodpecker co toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/woodpecker_co](https://composio.dev/toolkits/woodpecker_co)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Woodpecker co connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `woodpecker_co`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `woodpecker_co`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Woodpecker co operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Woodpecker co task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"woodpecker_co\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Woodpecker co-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `woodpecker_co` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/workable-automation/SKILL.md",
    "content": "---\nname: workable-automation\ndescription: \"Automate Workable tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Workable Automation via Rube MCP\n\nAutomate Workable operations through Composio's Workable toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/workable](https://composio.dev/toolkits/workable)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Workable connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `workable`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `workable`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Workable operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Workable task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"workable\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Workable-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `workable` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/workday-automation/SKILL.md",
    "content": "---\nname: Workday Automation\ndescription: \"Automate HR operations in Workday -- manage workers, time off requests, absence balances, and employee data through natural language commands.\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Workday Automation\n\nAutomate your Workday HR operations directly from Claude Code. Look up workers, create time off requests, check absence balances, and validate time off eligibility -- all without leaving your terminal.\n\n**Toolkit docs:** [composio.dev/toolkits/workday](https://composio.dev/toolkits/workday)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your Claude Code config with URL: `https://rube.app/mcp`\n2. When prompted, authenticate your Workday account through the connection link provided\n3. Start automating your HR workflows with natural language\n\n---\n\n## Core Workflows\n\n### 1. Search and List Workers\n\nRetrieve worker information with search and pagination.\n\n**Tool:** `WORKDAY_LIST_WORKERS`\n\n```\nSearch for workers named \"Sarah\" and include terminated employees\n```\n\nKey parameters:\n- `search` -- search by name or worker ID (case-insensitive, space-delimited for OR search)\n- `includeTerminatedWorkers` -- include terminated workers in results\n- `limit` (default 20, max 100) / `offset` -- pagination controls\n\n### 2. Create Time Off Requests\n\nSubmit time off requests for workers with full business process support.\n\n**Tool:** `WORKDAY_CREATE_TIME_OFF_REQUEST`\n\n```\nCreate a vacation request for worker abc123 for March 15-17, 2026 (8 hours each day)\n```\n\nKey parameters:\n- `ID` (required) -- Workday worker ID\n- `businessProcessParameters` (required) -- must include `action` with `id` field (use `\"d9e4223e446c11de98360015c5e6daf6\"` for submit action)\n- `days` (required) -- array of time off entries, each with:\n  - `date` (required) -- date in `yyyy-mm-dd` format\n  - `timeOffType` (required) -- object with `id` of the eligible absence type\n  - `dailyQuantity` -- hours or days quantity\n  - `comment`, `start`, `end`, `position`, `reason` -- optional fields\n- `businessProcessParameters.comment` -- optional business process comment\n\n### 3. Check Time Off Eligibility\n\nValidate which dates a worker can take off before submitting a request.\n\n**Tool:** `WORKDAY_GET_WORKER_VALID_TIME_OFF_DATES`\n\n```\nCheck if worker abc123 is eligible to take time off on March 15, 2026\n```\n\nKey parameters:\n- `ID` (required) -- Workday worker ID\n- `date` -- specific date to validate (`yyyy-mm-dd`)\n- `position` -- filter by specific position ID\n- `timeOff` -- filter by specific time off plan/type ID\n- `limit` (max 100) / `offset` -- pagination\n\n### 4. View Absence Balances\n\nCheck remaining time off balances for workers across all plans.\n\n**Tool:** `WORKDAY_LIST_ABSENCE_BALANCES`\n\n```\nShow me absence balances for all workers in the organization\n```\n\n- Retrieves balances for time off plans and leave of absence types\n- Can be filtered by worker ID, category, and effective date\n\n### 5. Get Current User Profile\n\nRetrieve the authenticated worker's profile information.\n\n**Tool:** `WORKDAY_GET_CURRENT_USER`\n\n```\nShow me my Workday profile information\n```\n\n- No parameters required\n- Returns the authenticated worker's profile\n- Use this first to get the worker ID for subsequent operations\n\n### 6. View Time Off History\n\nRetrieve time off details and history for a specific worker.\n\n**Tool:** `WORKDAY_GET_WORKER_TIME_OFF_DETAILS`\n\n```\nShow me the time off history for worker abc123\n```\n\n- Retrieves a collection of time off details for the specified worker\n- Useful for auditing time off usage and remaining balances\n\n---\n\n## Known Pitfalls\n\n- **Worker ID resolution:** Always call `WORKDAY_GET_CURRENT_USER` or `WORKDAY_LIST_WORKERS` first to resolve Workday worker IDs. Worker IDs are Workday-specific UUIDs, not employee numbers.\n- **Time off type IDs must be valid:** The `timeOffType.id` in `WORKDAY_CREATE_TIME_OFF_REQUEST` must reference a valid eligible absence type for that worker. Use the \"Get Worker Eligible Absence Types\" flow to discover valid type IDs.\n- **Submit action ID:** The `businessProcessParameters.action.id` should be `\"d9e4223e446c11de98360015c5e6daf6\"` for the submit action. Using an incorrect ID will cause the business process to fail.\n- **Date format:** All date fields use `yyyy-mm-dd` format. ISO 8601 with timestamps is not accepted for date-only fields.\n- **Pagination limits:** The maximum `limit` is 100 across all Workday endpoints. Default is 20. Always paginate for complete datasets.\n- **Business process approval:** Creating a time off request initiates the business process but does not guarantee approval. The request enters the normal approval workflow.\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|---|---|\n| `WORKDAY_LIST_WORKERS` | Search and list workers with staffing info |\n| `WORKDAY_GET_CURRENT_USER` | Get the authenticated worker's profile |\n| `WORKDAY_CREATE_TIME_OFF_REQUEST` | Submit a time off request (requires `ID`, `businessProcessParameters`, `days`) |\n| `WORKDAY_GET_WORKER_VALID_TIME_OFF_DATES` | Check time off date eligibility (requires `ID`) |\n| `WORKDAY_LIST_ABSENCE_BALANCES` | Retrieve absence balances across time off plans |\n| `WORKDAY_GET_WORKER_TIME_OFF_DETAILS` | Get time off history for a worker |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/workiom-automation/SKILL.md",
    "content": "---\nname: workiom-automation\ndescription: \"Automate Workiom tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Workiom Automation via Rube MCP\n\nAutomate Workiom operations through Composio's Workiom toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/workiom](https://composio.dev/toolkits/workiom)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Workiom connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `workiom`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `workiom`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Workiom operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Workiom task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"workiom\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Workiom-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `workiom` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/worksnaps-automation/SKILL.md",
    "content": "---\nname: worksnaps-automation\ndescription: \"Automate Worksnaps tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Worksnaps Automation via Rube MCP\n\nAutomate Worksnaps operations through Composio's Worksnaps toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/worksnaps](https://composio.dev/toolkits/worksnaps)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Worksnaps connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `worksnaps`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `worksnaps`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Worksnaps operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Worksnaps task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"worksnaps\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Worksnaps-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `worksnaps` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/writer-automation/SKILL.md",
    "content": "---\nname: writer-automation\ndescription: \"Automate Writer tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Writer Automation via Rube MCP\n\nAutomate Writer operations through Composio's Writer toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/writer](https://composio.dev/toolkits/writer)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Writer connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `writer`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `writer`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Writer operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Writer task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"writer\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Writer-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `writer` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/xero-automation/SKILL.md",
    "content": "---\nname: Xero Automation\ndescription: \"Xero Automation: manage invoices, contacts, payments, bank transactions, and accounts in Xero for cloud-based bookkeeping\"\nrequires:\n  mcp: [rube]\n---\n\n# Xero Automation\n\nAutomate Xero accounting operations including managing invoices, contacts, payments, bank transactions, and chart of accounts for small business bookkeeping.\n\n**Toolkit docs:** [composio.dev/toolkits/xero](https://composio.dev/toolkits/xero)\n\n---\n\n## Setup\n\nThis skill requires the **Rube MCP server** connected at `https://rube.app/mcp`.\n\nBefore executing any tools, ensure an active connection exists for the `xero` toolkit. If no connection is active, initiate one via `RUBE_MANAGE_CONNECTIONS`.\n\n**Multi-tenant:** If you manage multiple Xero organizations, first call `XERO_GET_CONNECTIONS` to list active tenants and obtain the correct `tenant_id` for subsequent calls.\n\n---\n\n## Core Workflows\n\n### 1. List and Filter Invoices\n\nRetrieve invoices with filtering by status, contact, date range, and pagination.\n\n**Tool:** `XERO_LIST_INVOICES`\n\n**Key Parameters:**\n- `Statuses` -- Comma-separated status filter: `\"DRAFT\"`, `\"SUBMITTED\"`, `\"AUTHORISED\"`, `\"PAID\"`\n- `ContactIDs` -- Comma-separated Contact IDs to filter by\n- `InvoiceIDs` -- Comma-separated Invoice IDs to filter by\n- `where` -- OData-style filter, e.g., `\"Status==\\\"AUTHORISED\\\" AND Total>100\"`\n- `order` -- Sort expression, e.g., `\"Date DESC\"`, `\"InvoiceNumber ASC\"`\n- `page` -- Page number for pagination\n- `If-Modified-Since` -- UTC timestamp; returns only invoices modified since this date\n- `tenant_id` -- Xero organization ID (uses first tenant if omitted)\n\n**Example:**\n```\nTool: XERO_LIST_INVOICES\nArguments:\n  Statuses: \"AUTHORISED,PAID\"\n  order: \"Date DESC\"\n  page: 1\n```\n\n---\n\n### 2. Manage Contacts\n\nRetrieve and search contacts for use in invoices and transactions.\n\n**Tool:** `XERO_GET_CONTACTS`\n\n**Key Parameters:**\n- `searchTerm` -- Case-insensitive search across Name, FirstName, LastName, Email, ContactNumber\n- `ContactID` -- Fetch a single contact by ID\n- `where` -- OData filter, e.g., `\"ContactStatus==\\\"ACTIVE\\\"\"`\n- `page`, `pageSize` -- Pagination controls\n- `order` -- Sort, e.g., `\"UpdatedDateUTC DESC\"`\n- `includeArchived` -- Include archived contacts when `true`\n- `summaryOnly` -- Lightweight response when `true`\n\n**Example:**\n```\nTool: XERO_GET_CONTACTS\nArguments:\n  searchTerm: \"acme\"\n  page: 1\n  pageSize: 25\n```\n\n> **Note:** On high-volume accounts, some `where` filters (e.g., `IsCustomer`, `IsSupplier`) may be rejected by Xero. Fall back to `searchTerm` or pagination.\n\n---\n\n### 3. Create Payments\n\nLink an invoice to a bank account by creating a payment record.\n\n**Tool:** `XERO_CREATE_PAYMENT`\n\n**Key Parameters:**\n- `InvoiceID` (required) -- Xero Invoice ID the payment applies to\n- `AccountID` (required) -- Bank account ID for the payment\n- `Amount` (required) -- Payment amount (number)\n- `Date` -- Payment date in `YYYY-MM-DD` format\n- `Reference` -- Payment reference or description\n- `CurrencyRate` -- Exchange rate for foreign currency payments\n\n**Example:**\n```\nTool: XERO_CREATE_PAYMENT\nArguments:\n  InvoiceID: \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"\n  AccountID: \"b2c3d4e5-f6a7-8901-bcde-f12345678901\"\n  Amount: 1500.00\n  Date: \"2026-02-11\"\n  Reference: \"Payment for INV-0042\"\n```\n\n---\n\n### 4. Create Bank Transactions\n\nRecord spend (payments out) or receive (money in) bank transactions.\n\n**Tool:** `XERO_CREATE_BANK_TRANSACTION`\n\n**Key Parameters:**\n- `Type` (required) -- `\"SPEND\"` (payment out) or `\"RECEIVE\"` (money in)\n- `ContactID` (required) -- Xero Contact ID\n- `BankAccountCode` (required) -- Bank account code from chart of accounts\n- `LineItems` (required) -- Array of line items, each with:\n  - `Description` (required) -- Line item description\n  - `UnitAmount` (required) -- Unit price\n  - `AccountCode` (required) -- Account code for categorization\n  - `Quantity` -- Quantity (default 1)\n  - `TaxType` -- Tax type: `\"OUTPUT\"`, `\"INPUT\"`, `\"NONE\"`\n- `Date` -- Transaction date in `YYYY-MM-DD` format\n- `Reference` -- Transaction reference\n- `Status` -- `\"AUTHORISED\"` or `\"DELETED\"`\n- `CurrencyCode` -- e.g., `\"USD\"`, `\"EUR\"`\n\n**Example:**\n```\nTool: XERO_CREATE_BANK_TRANSACTION\nArguments:\n  Type: \"SPEND\"\n  ContactID: \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"\n  BankAccountCode: \"090\"\n  LineItems: [\n    {\n      \"Description\": \"Office supplies\",\n      \"UnitAmount\": 75.00,\n      \"AccountCode\": \"429\",\n      \"Quantity\": 1,\n      \"TaxType\": \"INPUT\"\n    }\n  ]\n  Date: \"2026-02-11\"\n  Reference: \"Feb office supplies\"\n```\n\n---\n\n### 5. List Payments and Bank Transactions\n\nReview existing payments and bank transaction history.\n\n**Tools:**\n- `XERO_LIST_PAYMENTS` -- List payments linking invoices to bank transactions\n- `XERO_LIST_BANK_TRANSACTIONS` -- List spend/receive bank transactions\n\n**Common Parameters:**\n- `where` -- OData filter, e.g., `\"Status==\\\"AUTHORISED\\\"\"`\n- `order` -- Sort expression, e.g., `\"Date DESC\"`\n- `page` -- Page number for pagination\n- `If-Modified-Since` -- Incremental updates since timestamp\n- `tenant_id` -- Organization ID\n\n---\n\n### 6. View Chart of Accounts and Connections\n\n**Tools:**\n- `XERO_LIST_ACCOUNTS` -- Retrieve all account codes for categorizing transactions\n- `XERO_GET_CONNECTIONS` -- List active Xero tenant connections\n- `XERO_LIST_ATTACHMENTS` -- List attachments on an entity (invoice, contact, etc.)\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Detail |\n|---------|--------|\n| **Multi-tenant routing** | If `tenant_id` is omitted, the first connected tenant is used. Always verify the correct tenant with `XERO_GET_CONNECTIONS` when managing multiple organizations. |\n| **High-volume filter rejection** | On large accounts, some `where` filters like `IsCustomer`/`IsSupplier` may be rejected. Fall back to `searchTerm` with pagination. |\n| **OData filter syntax** | Use double-equals (`==`) in OData filters, e.g., `Status==\\\"AUTHORISED\\\"`. Single `=` causes errors. |\n| **Pagination required** | Most list endpoints paginate results. Always check for additional pages and continue fetching until complete. |\n| **Date format** | All dates must be in `YYYY-MM-DD` format. Timestamps for `If-Modified-Since` must be full ISO 8601 UTC datetime. |\n| **Bank account codes** | `BankAccountCode` in bank transactions must match a valid code from the chart of accounts. Use `XERO_LIST_ACCOUNTS` to discover valid codes. |\n\n---\n\n## Quick Reference\n\n| Tool Slug | Description |\n|-----------|-------------|\n| `XERO_LIST_INVOICES` | List invoices with filtering and pagination |\n| `XERO_GET_CONTACTS` | Retrieve and search contacts |\n| `XERO_CREATE_PAYMENT` | Create a payment linking invoice to bank account |\n| `XERO_CREATE_BANK_TRANSACTION` | Record a spend or receive bank transaction |\n| `XERO_LIST_PAYMENTS` | List payment records |\n| `XERO_LIST_BANK_TRANSACTIONS` | List bank transactions |\n| `XERO_LIST_ACCOUNTS` | Retrieve chart of accounts |\n| `XERO_GET_CONNECTIONS` | List active Xero tenant connections |\n| `XERO_LIST_ATTACHMENTS` | List attachments on an entity |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/y-gy-automation/SKILL.md",
    "content": "---\nname: y-gy-automation\ndescription: \"Automate Y Gy tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Y Gy Automation via Rube MCP\n\nAutomate Y Gy operations through Composio's Y Gy toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/y_gy](https://composio.dev/toolkits/y_gy)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Y Gy connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `y_gy`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `y_gy`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Y Gy operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Y Gy task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"y_gy\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Y Gy-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `y_gy` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/yandex-automation/SKILL.md",
    "content": "---\nname: yandex-automation\ndescription: \"Automate Yandex tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Yandex Automation via Rube MCP\n\nAutomate Yandex operations through Composio's Yandex toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/yandex](https://composio.dev/toolkits/yandex)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Yandex connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `yandex`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `yandex`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Yandex operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Yandex task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"yandex\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Yandex-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `yandex` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/yelp-automation/SKILL.md",
    "content": "---\nname: yelp-automation\ndescription: \"Automate Yelp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Yelp Automation via Rube MCP\n\nAutomate Yelp operations through Composio's Yelp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/yelp](https://composio.dev/toolkits/yelp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Yelp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `yelp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `yelp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Yelp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Yelp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"yelp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Yelp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `yelp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/ynab-automation/SKILL.md",
    "content": "---\nname: ynab-automation\ndescription: \"Automate Ynab tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Ynab Automation via Rube MCP\n\nAutomate Ynab operations through Composio's Ynab toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/ynab](https://composio.dev/toolkits/ynab)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Ynab connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `ynab`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `ynab`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Ynab operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Ynab task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"ynab\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Ynab-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `ynab` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/yousearch-automation/SKILL.md",
    "content": "---\nname: yousearch-automation\ndescription: \"Automate Yousearch tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Yousearch Automation via Rube MCP\n\nAutomate Yousearch operations through Composio's Yousearch toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/yousearch](https://composio.dev/toolkits/yousearch)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Yousearch connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `yousearch`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `yousearch`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Yousearch operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Yousearch task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"yousearch\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Yousearch-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `yousearch` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zenrows-automation/SKILL.md",
    "content": "---\nname: zenrows-automation\ndescription: \"Automate Zenrows tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zenrows Automation via Rube MCP\n\nAutomate Zenrows operations through Composio's Zenrows toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zenrows](https://composio.dev/toolkits/zenrows)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zenrows connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zenrows`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zenrows`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zenrows operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zenrows task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zenrows\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zenrows-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zenrows` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zenserp-automation/SKILL.md",
    "content": "---\nname: zenserp-automation\ndescription: \"Automate Zenserp tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zenserp Automation via Rube MCP\n\nAutomate Zenserp operations through Composio's Zenserp toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zenserp](https://composio.dev/toolkits/zenserp)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zenserp connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zenserp`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zenserp`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zenserp operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zenserp task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zenserp\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zenserp-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zenserp` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zeplin-automation/SKILL.md",
    "content": "---\nname: zeplin-automation\ndescription: \"Automate Zeplin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zeplin Automation via Rube MCP\n\nAutomate Zeplin operations through Composio's Zeplin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zeplin](https://composio.dev/toolkits/zeplin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zeplin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zeplin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zeplin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zeplin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zeplin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zeplin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zeplin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zeplin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zerobounce-automation/SKILL.md",
    "content": "---\nname: zerobounce-automation\ndescription: \"Automate Zerobounce tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zerobounce Automation via Rube MCP\n\nAutomate Zerobounce operations through Composio's Zerobounce toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zerobounce](https://composio.dev/toolkits/zerobounce)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zerobounce connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zerobounce`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zerobounce`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zerobounce operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zerobounce task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zerobounce\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zerobounce-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zerobounce` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-automation/SKILL.md",
    "content": "---\nname: zoho-automation\ndescription: \"Automate Zoho tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Automation via Rube MCP\n\nAutomate Zoho operations through Composio's Zoho toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho](https://composio.dev/toolkits/zoho)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoho operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoho task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoho\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-bigin-automation/SKILL.md",
    "content": "---\nname: zoho-bigin-automation\ndescription: \"Automate Zoho Bigin tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Bigin Automation via Rube MCP\n\nAutomate Zoho Bigin operations through Composio's Zoho Bigin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_bigin](https://composio.dev/toolkits/zoho_bigin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Bigin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoho Bigin operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoho Bigin task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoho_bigin\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Bigin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-books-automation/SKILL.md",
    "content": "---\nname: Zoho Books Automation\ndescription: \"Automate Zoho Books accounting workflows including invoice creation, bill management, contact lookup, payment tracking, and multi-organization support through natural language commands\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Zoho Books Automation\n\nAutomate Zoho Books accounting workflows -- create and manage invoices, track bills and payments, look up contacts, export PDFs, and handle multi-organization setups -- all through natural language.\n\n**Toolkit docs:** [composio.dev/toolkits/zoho_books](https://composio.dev/toolkits/zoho_books)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Connect your Zoho Books account when prompted (OAuth flow via Composio)\n3. Start issuing natural language commands for Zoho Books automation\n\n---\n\n## Core Workflows\n\n### 1. Discover Organizations\n\nRetrieve all organizations for the authenticated user. This is a prerequisite since `organization_id` is required by nearly every other endpoint.\n\n**Tool:** `ZOHO_BOOKS_LIST_ORGANIZATIONS`\n\nNo parameters required. Returns organization IDs, names, and metadata.\n\n> Always call this first to obtain the `organization_id` needed by all other Zoho Books tools.\n\nExample prompt:\n> \"List my Zoho Books organizations\"\n\n---\n\n### 2. Create and Manage Invoices\n\nCreate invoices with line items, manage existing invoices, and export them as PDFs.\n\n**Create:** `ZOHO_BOOKS_CREATE_INVOICE`\n\nKey parameters:\n- `organization_id` -- target organization (required)\n- `customer_id` -- customer to bill (required)\n- `line_items` -- array of line items (required), each with:\n  - `item_id` or `name` -- reference existing item or create ad-hoc line\n  - `quantity`, `rate` -- amount details\n  - `description`, `tax_id`, `discount` -- optional details\n- `date` / `due_date` -- dates in `YYYY-MM-DD` format\n- `invoice_number` -- custom number (set `ignore_auto_number_generation=true`)\n- `discount` / `discount_type` -- invoice-level discount (`entity_level` or `item_level`)\n- `notes` / `terms` -- printed on the invoice\n- `send` -- email the invoice immediately after creation\n- `payment_terms` -- number of days for payment\n\n**List:** `ZOHO_BOOKS_LIST_INVOICES`\n\nKey parameters:\n- `organization_id` (required)\n- `status` -- `sent`, `draft`, `overdue`, `paid`, `void`, `unpaid`, `partially_paid`, `viewed`\n- `customer_id` / `customer_name` -- filter by customer\n- `date_start` / `date_end` -- date range filter (`YYYY-MM-DD`)\n- `search_text` -- search invoice number, reference, or customer name\n- `sort_column` / `sort_order` -- sort by `date`, `due_date`, `total`, `balance`, etc.\n- `page` / `per_page` -- pagination (max 200 per page)\n\n**Get details:** `ZOHO_BOOKS_GET_INVOICE` -- fetch by `invoice_id` with `accept` format: `json`, `pdf`, or `html`\n\n**Delete:** `ZOHO_BOOKS_DELETE_INVOICE` -- remove by `invoice_id`\n\n**Bulk export:** `ZOHO_BOOKS_BULK_EXPORT_INVOICES_PDF` -- merge up to 25 invoices into a single PDF\n\n**Bulk print:** `ZOHO_BOOKS_BULK_PRINT_INVOICES` -- generate a combined print-ready PDF for up to 25 invoices\n\nExample prompt:\n> \"Create an invoice for customer 1234567890 with 2 line items: 10 units of Widget A at $25 each, and 5 units of Widget B at $50 each, due in 30 days\"\n\n---\n\n### 3. Track and Manage Bills\n\nList, view, and update vendor bills with comprehensive filtering.\n\n**List:** `ZOHO_BOOKS_LIST_BILLS`\n\nKey parameters:\n- `organization_id` (required)\n- `status` -- `paid`, `open`, `overdue`, `void`, `partially_paid`\n- `vendor_id` / `vendor_name_contains` -- filter by vendor\n- `bill_number` / `bill_number_contains` -- filter by bill number\n- `date_start` / `date_end` -- date range filter\n- `total_greater_than` / `total_less_than` -- amount range filters\n- `sort_column` / `sort_order` -- sort by `vendor_name`, `bill_number`, `date`, `due_date`, `total`, etc.\n- `page` / `per_page` -- pagination (max 200)\n\n**Get details:** `ZOHO_BOOKS_GET_BILL` -- fetch full bill by `bill_id` and `organization_id`\n\n**Update:** `ZOHO_BOOKS_UPDATE_BILL` -- modify existing bill (requires `bill_id`, `organization_id`, `vendor_id`, `bill_number`)\n\nExample prompt:\n> \"List all overdue bills for my organization, sorted by due date\"\n\n---\n\n### 4. Look Up Contacts\n\nSearch and filter contacts (customers and vendors) for use in invoices and bills.\n\n**Tool:** `ZOHO_BOOKS_LIST_CONTACTS`\n\nKey parameters:\n- `organization_id` (required)\n- `contact_type` -- `customer` or `vendor`\n- `contact_name_contains` / `contact_name_startswith` -- name filters\n- `email_contains` / `email_startswith` -- email filters\n- `company_name_contains` -- company name filter\n- `filter_by` -- status filter: `Status.Active`, `Status.Inactive`, `Status.Duplicate`, etc.\n- `search_text` -- search by contact name or notes (max 100 chars)\n- `sort_column` -- sort by `contact_name`, `email`, `outstanding_receivable_amount`, `created_time`, etc.\n- `page` / `per_page` -- pagination (max 200)\n\nExample prompt:\n> \"Find all active customers whose company name contains 'Acme'\"\n\n---\n\n### 5. Track Invoice Payments\n\nList all payments recorded against a specific invoice.\n\n**Tool:** `ZOHO_BOOKS_LIST_INVOICE_PAYMENTS`\n\nKey parameters:\n- `invoice_id` -- the invoice to check (required)\n- `organization_id` -- the organization (required)\n\nReturns all payment transactions applied to the invoice including amounts, dates, and payment methods.\n\nExample prompt:\n> \"Show all payments recorded against invoice 451025000000123045\"\n\n---\n\n### 6. Full Invoicing Workflow\n\nCombine tools for end-to-end invoice management:\n\n1. **Organization**: `ZOHO_BOOKS_LIST_ORGANIZATIONS` -- get `organization_id`\n2. **Contacts**: `ZOHO_BOOKS_LIST_CONTACTS` -- find or verify `customer_id`\n3. **Create**: `ZOHO_BOOKS_CREATE_INVOICE` -- create invoice with line items\n4. **Review**: `ZOHO_BOOKS_GET_INVOICE` -- fetch invoice details or PDF\n5. **Track**: `ZOHO_BOOKS_LIST_INVOICE_PAYMENTS` -- monitor payment status\n6. **Export**: `ZOHO_BOOKS_BULK_EXPORT_INVOICES_PDF` -- batch export for records\n\nExample prompt:\n> \"Find the customer ID for 'Acme Corp', create an invoice for them with consulting services, and then get the PDF\"\n\n---\n\n## Known Pitfalls\n\n| Pitfall | Details |\n|---------|---------|\n| Organization ID always required | Nearly every endpoint requires `organization_id` -- always call `ZOHO_BOOKS_LIST_ORGANIZATIONS` first |\n| Line items required for invoices | `ZOHO_BOOKS_CREATE_INVOICE` requires at least one line item with either `item_id` or `name` |\n| Invoice ID format | Use the numeric `invoice_id` from the invoice object (e.g., `7472322000000264123`), not the encoded ID from `invoice_url` |\n| Bulk limits | Both `ZOHO_BOOKS_BULK_EXPORT_INVOICES_PDF` and `ZOHO_BOOKS_BULK_PRINT_INVOICES` accept a maximum of 25 invoice IDs |\n| Pagination max 200 | All list endpoints cap at 200 records per page -- iterate pages for complete results |\n| Bill update requires all fields | `ZOHO_BOOKS_UPDATE_BILL` requires `bill_id`, `organization_id`, `vendor_id`, and `bill_number` even for partial updates |\n| Date format | All date parameters use `YYYY-MM-DD` format |\n| response_option undocumented | `ZOHO_BOOKS_LIST_INVOICES` has an undocumented `response_option` parameter (0=full, 1=full+totals, 2=counts only) that may change without notice |\n\n---\n\n## Quick Reference\n\n| Action | Tool Slug | Key Params |\n|--------|-----------|------------|\n| List organizations | `ZOHO_BOOKS_LIST_ORGANIZATIONS` | (none) |\n| Create invoice | `ZOHO_BOOKS_CREATE_INVOICE` | `organization_id`, `customer_id`, `line_items` |\n| List invoices | `ZOHO_BOOKS_LIST_INVOICES` | `organization_id`, `status`, `date_start` |\n| Get invoice | `ZOHO_BOOKS_GET_INVOICE` | `invoice_id`, `organization_id`, `accept` |\n| Delete invoice | `ZOHO_BOOKS_DELETE_INVOICE` | `invoice_id`, `organization_id` |\n| Bulk export PDF | `ZOHO_BOOKS_BULK_EXPORT_INVOICES_PDF` | `organization_id`, `invoice_ids` |\n| Bulk print | `ZOHO_BOOKS_BULK_PRINT_INVOICES` | `organization_id`, `invoice_ids` |\n| List bills | `ZOHO_BOOKS_LIST_BILLS` | `organization_id`, `status`, `vendor_id` |\n| Get bill | `ZOHO_BOOKS_GET_BILL` | `bill_id`, `organization_id` |\n| Update bill | `ZOHO_BOOKS_UPDATE_BILL` | `bill_id`, `organization_id`, `vendor_id` |\n| List contacts | `ZOHO_BOOKS_LIST_CONTACTS` | `organization_id`, `contact_type`, `search_text` |\n| List payments | `ZOHO_BOOKS_LIST_INVOICE_PAYMENTS` | `invoice_id`, `organization_id` |\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-desk-automation/SKILL.md",
    "content": "---\nname: Zoho Desk Automation\ndescription: \"Zoho Desk automation via Rube MCP -- toolkit not currently available in Composio; no ZOHO_DESK_ tools found\"\nrequires:\n  mcp:\n    - rube\n---\n\n# Zoho Desk Automation\n\n> **Status: Toolkit Not Available** -- RUBE_SEARCH_TOOLS returned no `zoho_desk`-specific tools. The Zoho Desk toolkit is not currently available in Composio's tool catalog. Searches returned tools from unrelated helpdesk and CRM toolkits instead.\n\n**Toolkit docs:** [composio.dev/toolkits/zoho_desk](https://composio.dev/toolkits/zoho_desk)\n\n---\n\n## Setup\n\n1. Add the Rube MCP server to your environment: `https://rube.app/mcp`\n2. Check availability by calling `RUBE_SEARCH_TOOLS` with Zoho Desk-related queries\n3. If `ZOHO_DESK_*` tools appear in the future, connect via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_desk`\n\n---\n\n## Current Status\n\nAs of the last tool discovery scan, no `ZOHO_DESK_*` tool slugs were returned by RUBE_SEARCH_TOOLS. Queries for Zoho Desk ticket management, contacts, agents, and departments all returned tools from other toolkits:\n\n- Ticket creation queries returned **Freshdesk** (`FRESHDESK_CREATE_TICKET`), **HubSpot** (`HUBSPOT_CREATE_TICKET`), and **Zendesk** (`ZENDESK_CREATE_ZENDESK_TICKET`) tools\n- Contact listing queries returned **Zoho Invoice** (`ZOHO_INVOICE_LIST_CONTACTS`) tools\n- Agent/department queries returned **Zoho CRM** (`ZOHO_GET_ZOHO_USERS`) tools\n\nThis indicates the `zoho_desk` toolkit either has no tools registered or is not yet integrated into the Composio platform.\n\n---\n\n## Alternatives\n\nIf you need helpdesk and support ticket automation, consider these available toolkits:\n\n| Need | Alternative Toolkit | Example Tools |\n|------|-------------------|---------------|\n| Ticket management | Freshdesk | `FRESHDESK_CREATE_TICKET`, `FRESHDESK_UPDATE_TICKET` |\n| Ticket management | Zendesk | `ZENDESK_CREATE_ZENDESK_TICKET` |\n| Ticket management | HubSpot | `HUBSPOT_CREATE_TICKET`, `HUBSPOT_LIST_TICKETS` |\n| CRM records | Zoho CRM | `ZOHO_CREATE_ZOHO_RECORD`, `ZOHO_GET_ZOHO_USERS` |\n| Contact management | Zoho Invoice | `ZOHO_INVOICE_LIST_CONTACTS` |\n\n---\n\n## When Tools Become Available\n\nOnce Zoho Desk tools are added to Composio, this skill should be updated with real tool slugs, schemas, and pitfalls following the same pattern as other automation skills in this collection.\n\n---\n\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-inventory-automation/SKILL.md",
    "content": "---\nname: zoho-inventory-automation\ndescription: \"Automate Zoho Inventory tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Inventory Automation via Rube MCP\n\nAutomate Zoho Inventory operations through Composio's Zoho Inventory toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_inventory](https://composio.dev/toolkits/zoho_inventory)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Inventory connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoho Inventory operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoho Inventory task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoho_inventory\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Inventory-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-invoice-automation/SKILL.md",
    "content": "---\nname: zoho-invoice-automation\ndescription: \"Automate Zoho Invoice tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Invoice Automation via Rube MCP\n\nAutomate Zoho Invoice operations through Composio's Zoho Invoice toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_invoice](https://composio.dev/toolkits/zoho_invoice)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Invoice connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoho Invoice operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoho Invoice task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoho_invoice\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Invoice-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho-mail-automation/SKILL.md",
    "content": "---\nname: zoho-mail-automation\ndescription: \"Automate Zoho Mail tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Mail Automation via Rube MCP\n\nAutomate Zoho Mail operations through Composio's Zoho Mail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_mail](https://composio.dev/toolkits/zoho_mail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Mail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoho Mail operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoho Mail task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoho_mail\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Mail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zoho_bigin-automation/SKILL.md",
    "content": "---\nname: zoho_bigin-automation\ndescription: \"Automate Zoho Bigin tasks via Rube MCP (Composio): pipelines, contacts, companies, products, and small business CRM. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Bigin Automation via Rube MCP\n\nAutomate Zoho Bigin operations through Composio's Zoho Bigin toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_bigin](https://composio.dev/toolkits/zoho_bigin)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Bigin connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"pipelines, contacts, companies, products, and small business CRM\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Bigin\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Bigin Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Bigin tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Bigin Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Bigin operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Bigin connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Bigin-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_bigin` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_bigin](https://composio.dev/toolkits/zoho_bigin)\n"
  },
  {
    "path": "composio-skills/zoho_books-automation/SKILL.md",
    "content": "---\nname: zoho_books-automation\ndescription: \"Automate Zoho Books tasks via Rube MCP (Composio): invoices, expenses, contacts, payments, and accounting. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Books Automation via Rube MCP\n\nAutomate Zoho Books operations through Composio's Zoho Books toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_books](https://composio.dev/toolkits/zoho_books)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Books connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_books`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_books`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"invoices, expenses, contacts, payments, and accounting\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Books\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Books Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Books tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Books Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Books operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Books connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Books-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_books` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_books](https://composio.dev/toolkits/zoho_books)\n"
  },
  {
    "path": "composio-skills/zoho_desk-automation/SKILL.md",
    "content": "---\nname: zoho_desk-automation\ndescription: \"Automate Zoho Desk tasks via Rube MCP (Composio): tickets, contacts, agents, departments, and help desk operations. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Desk Automation via Rube MCP\n\nAutomate Zoho Desk operations through Composio's Zoho Desk toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_desk](https://composio.dev/toolkits/zoho_desk)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Desk connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_desk`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_desk`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"tickets, contacts, agents, departments, and help desk operations\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Desk\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Desk Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Desk tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Desk Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Desk operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Desk connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Desk-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_desk` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_desk](https://composio.dev/toolkits/zoho_desk)\n"
  },
  {
    "path": "composio-skills/zoho_inventory-automation/SKILL.md",
    "content": "---\nname: zoho_inventory-automation\ndescription: \"Automate Zoho Inventory tasks via Rube MCP (Composio): items, orders, warehouses, shipments, and stock management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Inventory Automation via Rube MCP\n\nAutomate Zoho Inventory operations through Composio's Zoho Inventory toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_inventory](https://composio.dev/toolkits/zoho_inventory)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Inventory connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"items, orders, warehouses, shipments, and stock management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Inventory\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Inventory Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Inventory tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Inventory Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Inventory operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Inventory connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Inventory-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_inventory` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_inventory](https://composio.dev/toolkits/zoho_inventory)\n"
  },
  {
    "path": "composio-skills/zoho_invoice-automation/SKILL.md",
    "content": "---\nname: zoho_invoice-automation\ndescription: \"Automate Zoho Invoice tasks via Rube MCP (Composio): invoices, estimates, expenses, clients, and payment tracking. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Invoice Automation via Rube MCP\n\nAutomate Zoho Invoice operations through Composio's Zoho Invoice toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_invoice](https://composio.dev/toolkits/zoho_invoice)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Invoice connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"invoices, estimates, expenses, clients, and payment tracking\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Invoice\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Invoice Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Invoice tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Invoice Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Invoice operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Invoice connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Invoice-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_invoice` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_invoice](https://composio.dev/toolkits/zoho_invoice)\n"
  },
  {
    "path": "composio-skills/zoho_mail-automation/SKILL.md",
    "content": "---\nname: zoho_mail-automation\ndescription: \"Automate Zoho Mail tasks via Rube MCP (Composio): email sending, folders, labels, and mailbox management. Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoho Mail Automation via Rube MCP\n\nAutomate Zoho Mail operations through Composio's Zoho Mail toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoho_mail](https://composio.dev/toolkits/zoho_mail)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoho Mail connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS: queries=[{\"use_case\": \"email sending, folders, labels, and mailbox management\", \"known_fields\": \"\"}]\n```\n\nThis returns:\n- Available tool slugs for Zoho Mail\n- Recommended execution plan steps\n- Known pitfalls and edge cases\n- Input schemas for each tool\n\n## Core Workflows\n\n### 1. Discover Available Zoho Mail Tools\n\n```\nRUBE_SEARCH_TOOLS:\n  queries:\n    - use_case: \"list all available Zoho Mail tools and capabilities\"\n```\n\nReview the returned tools, their descriptions, and input schemas before proceeding.\n\n### 2. Execute Zoho Mail Operations\n\nAfter discovering tools, execute them via:\n\n```\nRUBE_MULTI_EXECUTE_TOOL:\n  tools:\n    - tool_slug: \"<discovered_tool_slug>\"\n      arguments: {<schema-compliant arguments>}\n  memory: {}\n  sync_response_to_workbench: false\n```\n\n### 3. Multi-Step Workflows\n\nFor complex workflows involving multiple Zoho Mail operations:\n\n1. Search for all relevant tools: `RUBE_SEARCH_TOOLS` with specific use case\n2. Execute prerequisite steps first (e.g., fetch before update)\n3. Pass data between steps using tool responses\n4. Use `RUBE_REMOTE_WORKBENCH` for bulk operations or data processing\n\n## Common Patterns\n\n### Search Before Action\nAlways search for existing resources before creating new ones to avoid duplicates.\n\n### Pagination\nMany list operations support pagination. Check responses for `next_cursor` or `page_token` and continue fetching until exhausted.\n\n### Error Handling\n- Check tool responses for errors before proceeding\n- If a tool fails, verify the connection is still ACTIVE\n- Re-authenticate via `RUBE_MANAGE_CONNECTIONS` if connection expired\n\n### Batch Operations\nFor bulk operations, use `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` in a loop with `ThreadPoolExecutor` for parallel execution.\n\n## Known Pitfalls\n\n- **Always search tools first**: Tool schemas and available operations may change. Never hardcode tool slugs without first discovering them via `RUBE_SEARCH_TOOLS`.\n- **Check connection status**: Ensure the Zoho Mail connection is ACTIVE before executing any tools. Expired OAuth tokens require re-authentication.\n- **Respect rate limits**: If you receive rate limit errors, reduce request frequency and implement backoff.\n- **Validate schemas**: Always pass strictly schema-compliant arguments. Use `RUBE_GET_TOOL_SCHEMAS` to load full input schemas when `schemaRef` is returned instead of `input_schema`.\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoho Mail-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoho_mail` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n> **Toolkit docs**: [composio.dev/toolkits/zoho_mail](https://composio.dev/toolkits/zoho_mail)\n"
  },
  {
    "path": "composio-skills/zoominfo-automation/SKILL.md",
    "content": "---\nname: zoominfo-automation\ndescription: \"Automate Zoominfo tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zoominfo Automation via Rube MCP\n\nAutomate Zoominfo operations through Composio's Zoominfo toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zoominfo](https://composio.dev/toolkits/zoominfo)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zoominfo connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zoominfo`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zoominfo`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zoominfo operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zoominfo task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zoominfo\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zoominfo-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zoominfo` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zylvie-automation/SKILL.md",
    "content": "---\nname: zylvie-automation\ndescription: \"Automate Zylvie tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zylvie Automation via Rube MCP\n\nAutomate Zylvie operations through Composio's Zylvie toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zylvie](https://composio.dev/toolkits/zylvie)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zylvie connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zylvie`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zylvie`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zylvie operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zylvie task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zylvie\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zylvie-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zylvie` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "composio-skills/zyte-api-automation/SKILL.md",
    "content": "---\nname: zyte-api-automation\ndescription: \"Automate Zyte API tasks via Rube MCP (Composio). Always search tools first for current schemas.\"\nrequires:\n  mcp: [rube]\n---\n\n# Zyte API Automation via Rube MCP\n\nAutomate Zyte API operations through Composio's Zyte API toolkit via Rube MCP.\n\n**Toolkit docs**: [composio.dev/toolkits/zyte_api](https://composio.dev/toolkits/zyte_api)\n\n## Prerequisites\n\n- Rube MCP must be connected (RUBE_SEARCH_TOOLS available)\n- Active Zyte API connection via `RUBE_MANAGE_CONNECTIONS` with toolkit `zyte_api`\n- Always call `RUBE_SEARCH_TOOLS` first to get current tool schemas\n\n## Setup\n\n**Get Rube MCP**: Add `https://rube.app/mcp` as an MCP server in your client configuration. No API keys needed — just add the endpoint and it works.\n\n1. Verify Rube MCP is available by confirming `RUBE_SEARCH_TOOLS` responds\n2. Call `RUBE_MANAGE_CONNECTIONS` with toolkit `zyte_api`\n3. If connection is not ACTIVE, follow the returned auth link to complete setup\n4. Confirm connection status shows ACTIVE before running any workflows\n\n## Tool Discovery\n\nAlways discover available tools before executing workflows:\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"Zyte API operations\", known_fields: \"\"}]\nsession: {generate_id: true}\n```\n\nThis returns available tool slugs, input schemas, recommended execution plans, and known pitfalls.\n\n## Core Workflow Pattern\n\n### Step 1: Discover Available Tools\n\n```\nRUBE_SEARCH_TOOLS\nqueries: [{use_case: \"your specific Zyte API task\"}]\nsession: {id: \"existing_session_id\"}\n```\n\n### Step 2: Check Connection\n\n```\nRUBE_MANAGE_CONNECTIONS\ntoolkits: [\"zyte_api\"]\nsession_id: \"your_session_id\"\n```\n\n### Step 3: Execute Tools\n\n```\nRUBE_MULTI_EXECUTE_TOOL\ntools: [{\n  tool_slug: \"TOOL_SLUG_FROM_SEARCH\",\n  arguments: {/* schema-compliant args from search results */}\n}]\nmemory: {}\nsession_id: \"your_session_id\"\n```\n\n## Known Pitfalls\n\n- **Always search first**: Tool schemas change. Never hardcode tool slugs or arguments without calling `RUBE_SEARCH_TOOLS`\n- **Check connection**: Verify `RUBE_MANAGE_CONNECTIONS` shows ACTIVE status before executing tools\n- **Schema compliance**: Use exact field names and types from the search results\n- **Memory parameter**: Always include `memory` in `RUBE_MULTI_EXECUTE_TOOL` calls, even if empty (`{}`)\n- **Session reuse**: Reuse session IDs within a workflow. Generate new ones for new workflows\n- **Pagination**: Check responses for pagination tokens and continue fetching until complete\n\n## Quick Reference\n\n| Operation | Approach |\n|-----------|----------|\n| Find tools | `RUBE_SEARCH_TOOLS` with Zyte API-specific use case |\n| Connect | `RUBE_MANAGE_CONNECTIONS` with toolkit `zyte_api` |\n| Execute | `RUBE_MULTI_EXECUTE_TOOL` with discovered tool slugs |\n| Bulk ops | `RUBE_REMOTE_WORKBENCH` with `run_composio_tool()` |\n| Full schema | `RUBE_GET_TOOL_SCHEMAS` for tools with `schemaRef` |\n\n---\n*Powered by [Composio](https://composio.dev)*\n"
  },
  {
    "path": "connect/SKILL.md",
    "content": "---\nname: connect\ndescription: Connect Claude to any app. Send emails, create issues, post messages, update databases - take real actions across Gmail, Slack, GitHub, Notion, and 1000+ services.\n---\n\n# Connect\n\nConnect Claude to any app. Stop generating text about what you could do - actually do it.\n\n## When to Use This Skill\n\nUse this skill when you need Claude to:\n\n- **Send that email** instead of drafting it\n- **Create that issue** instead of describing it\n- **Post that message** instead of suggesting it\n- **Update that database** instead of explaining how\n\n## What Changes\n\n| Without Connect | With Connect |\n|-----------------|--------------|\n| \"Here's a draft email...\" | Sends the email |\n| \"You should create an issue...\" | Creates the issue |\n| \"Post this to Slack...\" | Posts it |\n| \"Add this to Notion...\" | Adds it |\n\n## Supported Apps\n\n**1000+ integrations** including:\n\n- **Email:** Gmail, Outlook, SendGrid\n- **Chat:** Slack, Discord, Teams, Telegram\n- **Dev:** GitHub, GitLab, Jira, Linear\n- **Docs:** Notion, Google Docs, Confluence\n- **Data:** Sheets, Airtable, PostgreSQL\n- **CRM:** HubSpot, Salesforce, Pipedrive\n- **Storage:** Drive, Dropbox, S3\n- **Social:** Twitter, LinkedIn, Reddit\n\n## Setup\n\n### 1. Get API Key\n\nGet your free key at [platform.composio.dev](https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills)\n\n### 2. Set Environment Variable\n\n```bash\nexport COMPOSIO_API_KEY=\"your-key\"\n```\n\n### 3. Install\n\n```bash\npip install composio          # Python\nnpm install @composio/core    # TypeScript\n```\n\nDone. Claude can now connect to any app.\n\n## Examples\n\n### Send Email\n```\nEmail sarah@acme.com - Subject: \"Shipped!\" Body: \"v2.0 is live, let me know if issues\"\n```\n\n### Create GitHub Issue\n```\nCreate issue in my-org/repo: \"Mobile timeout bug\" with label:bug\n```\n\n### Post to Slack\n```\nPost to #engineering: \"Deploy complete - v2.4.0 live\"\n```\n\n### Chain Actions\n```\nFind GitHub issues labeled \"bug\" from this week, summarize, post to #bugs on Slack\n```\n\n## How It Works\n\nUses Composio Tool Router:\n\n1. **You ask** Claude to do something\n2. **Tool Router finds** the right tool (1000+ options)\n3. **OAuth handled** automatically\n4. **Action executes** and returns result\n\n### Code\n\n```python\nfrom composio import Composio\nfrom claude_agent_sdk.client import ClaudeSDKClient\nfrom claude_agent_sdk.types import ClaudeAgentOptions\nimport os\n\ncomposio = Composio(api_key=os.environ[\"COMPOSIO_API_KEY\"])\nsession = composio.create(user_id=\"user_123\")\n\noptions = ClaudeAgentOptions(\n    system_prompt=\"You can take actions in external apps.\",\n    mcp_servers={\n        \"composio\": {\n            \"type\": \"http\",\n            \"url\": session.mcp.url,\n            \"headers\": {\"x-api-key\": os.environ[\"COMPOSIO_API_KEY\"]},\n        }\n    },\n)\n\nasync with ClaudeSDKClient(options) as client:\n    await client.query(\"Send Slack message to #general: Hello!\")\n```\n\n## Auth Flow\n\nFirst time using an app:\n```\nTo send emails, I need Gmail access.\nAuthorize here: https://...\nSay \"connected\" when done.\n```\n\nConnection persists after that.\n\n## Framework Support\n\n| Framework | Install |\n|-----------|---------|\n| Claude Agent SDK | `pip install composio claude-agent-sdk` |\n| OpenAI Agents | `pip install composio openai-agents` |\n| Vercel AI | `npm install @composio/core @composio/vercel` |\n| LangChain | `pip install composio-langchain` |\n| Any MCP Client | Use `session.mcp.url` |\n\n## Troubleshooting\n\n- **Auth required** → Click link, authorize, say \"connected\"\n- **Action failed** → Check permissions in target app\n- **Tool not found** → Be specific: \"Slack #general\" not \"send message\"\n\n---\n\n<p align=\"center\">\n  <b>Join 20,000+ developers building agents that ship</b>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills\">\n    <img src=\"https://img.shields.io/badge/Get_Started_Free-4F46E5?style=for-the-badge\" alt=\"Get Started\"/>\n  </a>\n</p>\n"
  },
  {
    "path": "connect-apps/SKILL.md",
    "content": "---\nname: connect-apps\ndescription: Connect Claude to external apps like Gmail, Slack, GitHub. Use this skill when the user wants to send emails, create issues, post messages, or take actions in external services.\n---\n\n# Connect Apps\n\nConnect Claude to 1000+ apps. Actually send emails, create issues, post messages - not just generate text about it.\n\n## Quick Start\n\n### Step 1: Install the Plugin\n\n```\n/plugin install composio-toolrouter\n```\n\n### Step 2: Run Setup\n\n```\n/composio-toolrouter:setup\n```\n\nThis will:\n- Ask for your free API key (get one at [platform.composio.dev](https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills))\n- Configure Claude's connection to 1000+ apps\n- Take about 60 seconds\n\n### Step 3: Try It!\n\nAfter setup, restart Claude Code and try:\n\n```\nSend me a test email at YOUR_EMAIL@example.com\n```\n\nIf it works, you're connected!\n\n## What You Can Do\n\n| Ask Claude to... | What happens |\n|------------------|--------------|\n| \"Send email to sarah@acme.com about the launch\" | Actually sends the email |\n| \"Create GitHub issue: fix login bug\" | Creates the issue |\n| \"Post to Slack #general: deploy complete\" | Posts the message |\n| \"Add meeting notes to Notion\" | Adds to Notion |\n\n## Supported Apps\n\n**Email:** Gmail, Outlook, SendGrid\n**Chat:** Slack, Discord, Teams, Telegram\n**Dev:** GitHub, GitLab, Jira, Linear\n**Docs:** Notion, Google Docs, Confluence\n**Data:** Sheets, Airtable, PostgreSQL\n**And 1000+ more...**\n\n## How It Works\n\n1. You ask Claude to do something\n2. Composio Tool Router finds the right tool\n3. First time? You'll authorize via OAuth (one-time)\n4. Action executes and returns result\n\n## Troubleshooting\n\n- **\"Plugin not found\"** → Make sure you ran `/plugin install composio-toolrouter`\n- **\"Need to authorize\"** → Click the OAuth link Claude provides, then say \"done\"\n- **Action failed** → Check you have permissions in the target app\n\n---\n\n<p align=\"center\">\n  <b>Join 20,000+ developers building agents that ship</b>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills\">\n    <img src=\"https://img.shields.io/badge/Get_Started_Free-4F46E5?style=for-the-badge\" alt=\"Get Started\"/>\n  </a>\n</p>\n"
  },
  {
    "path": "connect-apps-plugin/.claude-plugin/plugin.json",
    "content": "{\n  \"name\": \"connect-apps\",\n  \"description\": \"Manage auth and connect to 500+ apps using Composio. Perform real actions from Claude Code - send emails, create issues, post messages, and more.\",\n  \"author\": {\n    \"name\": \"Composio\",\n    \"email\": \"support@composio.dev\"\n  }\n}\n"
  },
  {
    "path": "connect-apps-plugin/README.md",
    "content": "# Connect Apps Plugin\n\nLet Claude perform real actions in 500+ apps. Handles auth and connections using Composio under the hood.\n\n## Install\n\n```bash\nclaude --plugin-dir ./connect-apps-plugin\n```\n\nThen run the setup:\n```\n/connect-apps:setup\n```\n\n## What You Get\n\nOnce installed, Claude can:\n- **Send emails** via Gmail, Outlook\n- **Create issues** on GitHub, GitLab, Jira, Linear\n- **Post messages** to Slack, Discord, Teams\n- **Update docs** in Notion, Google Docs\n- **Manage data** in Sheets, Airtable, databases\n- **And 500+ more actions**\n\n## How It Works\n\n1. Get a free API key from [platform.composio.dev](https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills)\n2. Run `/connect-apps:setup` and paste your key\n3. Restart Claude Code\n4. First time using an app, you'll authorize via OAuth\n5. That's it - Claude can now take real actions\n\n## Try It\n\nAfter setup, ask Claude:\n```\nSend me a test email at myemail@example.com\n```\n\n---\n\n<p align=\"center\">\n  <a href=\"https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills\">\n    <img src=\"https://img.shields.io/badge/Get_API_Key-4F46E5?style=for-the-badge\" alt=\"Get API Key\"/>\n  </a>\n</p>\n"
  },
  {
    "path": "connect-apps-plugin/commands/setup.md",
    "content": "---\ndescription: Set up connect-apps - let Claude perform real actions in 500+ apps\nallowed-tools: [Bash, Write, AskUserQuestion]\n---\n\n# Connect Apps Setup\n\nSet up the connect-apps plugin so Claude can take real actions in external apps (Gmail, Slack, GitHub, etc). Uses Composio for auth and app connections.\n\n## Instructions\n\n### Step 1: Ask for API Key\n\nAsk the user for their Composio API key. If they don't have one, tell them to get a free key at: https://platform.composio.dev/?utm_source=Github&utm_content=AwesomeSkills\n\nJust ask for the key directly. Don't ask if they have one first.\n\n### Step 2: Validate & Get MCP URL\n\nRun this command (replace API_KEY_HERE with the actual key):\n\n```bash\n/opt/homebrew/bin/python3.11 -c \"\nfrom composio import Composio\ncomposio = Composio(api_key='API_KEY_HERE')\nsession = composio.create(user_id='claude_user')\nprint(session.mcp.url)\n\"\n```\n\nIf it fails with import error, first run: `pip3 install composio`\n\n### Step 3: Write Config\n\nWrite directly to `~/.mcp.json` with this exact format:\n\n```json\n{\n  \"connect-apps\": {\n    \"type\": \"http\",\n    \"url\": \"THE_MCP_URL_FROM_STEP_2\",\n    \"headers\": {\n      \"x-api-key\": \"THE_API_KEY\"\n    }\n  }\n}\n```\n\nIf ~/.mcp.json already exists with other servers, merge the \"connect-apps\" key into the existing JSON.\n\n### Step 4: Confirm\n\nTell the user:\n```\nSetup complete!\n\nTo activate: exit and run `claude` again\n\nThen try: \"Send me a test email at your@email.com\"\n```\n\n## Important\n\n- Do NOT try to edit settings.local.json - MCP servers go in ~/.mcp.json\n- Do NOT search for config locations - just write to ~/.mcp.json\n- Do NOT ask multiple questions - just ask for the API key once\n- Be fast - this should take under 30 seconds\n"
  },
  {
    "path": "content-research-writer/SKILL.md",
    "content": "---\nname: content-research-writer\ndescription: Assists in writing high-quality content by conducting research, adding citations, improving hooks, iterating on outlines, and providing real-time feedback on each section. Transforms your writing process from solo effort to collaborative partnership.\n---\n\n# Content Research Writer\n\nThis skill acts as your writing partner, helping you research, outline, draft, and refine content while maintaining your unique voice and style.\n\n## When to Use This Skill\n\n- Writing blog posts, articles, or newsletters\n- Creating educational content or tutorials\n- Drafting thought leadership pieces\n- Researching and writing case studies\n- Producing technical documentation with sources\n- Writing with proper citations and references\n- Improving hooks and introductions\n- Getting section-by-section feedback while writing\n\n## What This Skill Does\n\n1. **Collaborative Outlining**: Helps you structure ideas into coherent outlines\n2. **Research Assistance**: Finds relevant information and adds citations\n3. **Hook Improvement**: Strengthens your opening to capture attention\n4. **Section Feedback**: Reviews each section as you write\n5. **Voice Preservation**: Maintains your writing style and tone\n6. **Citation Management**: Adds and formats references properly\n7. **Iterative Refinement**: Helps you improve through multiple drafts\n\n## How to Use\n\n### Setup Your Writing Environment\n\nCreate a dedicated folder for your article:\n```\nmkdir ~/writing/my-article-title\ncd ~/writing/my-article-title\n```\n\nCreate your draft file:\n```\ntouch article-draft.md\n```\n\nOpen Claude Code from this directory and start writing.\n\n### Basic Workflow\n\n1. **Start with an outline**:\n```\nHelp me create an outline for an article about [topic]\n```\n\n2. **Research and add citations**:\n```\nResearch [specific topic] and add citations to my outline\n```\n\n3. **Improve the hook**:\n```\nHere's my introduction. Help me make the hook more compelling.\n```\n\n4. **Get section feedback**:\n```\nI just finished the \"Why This Matters\" section. Review it and give feedback.\n```\n\n5. **Refine and polish**:\n```\nReview the full draft for flow, clarity, and consistency.\n```\n\n## Instructions\n\nWhen a user requests writing assistance:\n\n1. **Understand the Writing Project**\n   \n   Ask clarifying questions:\n   - What's the topic and main argument?\n   - Who's the target audience?\n   - What's the desired length/format?\n   - What's your goal? (educate, persuade, entertain, explain)\n   - Any existing research or sources to include?\n   - What's your writing style? (formal, conversational, technical)\n\n2. **Collaborative Outlining**\n   \n   Help structure the content:\n   \n   ```markdown\n   # Article Outline: [Title]\n   \n   ## Hook\n   - [Opening line/story/statistic]\n   - [Why reader should care]\n   \n   ## Introduction\n   - Context and background\n   - Problem statement\n   - What this article covers\n   \n   ## Main Sections\n   \n   ### Section 1: [Title]\n   - Key point A\n   - Key point B\n   - Example/evidence\n   - [Research needed: specific topic]\n   \n   ### Section 2: [Title]\n   - Key point C\n   - Key point D\n   - Data/citation needed\n   \n   ### Section 3: [Title]\n   - Key point E\n   - Counter-arguments\n   - Resolution\n   \n   ## Conclusion\n   - Summary of main points\n   - Call to action\n   - Final thought\n   \n   ## Research To-Do\n   - [ ] Find data on [topic]\n   - [ ] Get examples of [concept]\n   - [ ] Source citation for [claim]\n   ```\n   \n   **Iterate on outline**:\n   - Adjust based on feedback\n   - Ensure logical flow\n   - Identify research gaps\n   - Mark sections for deep dives\n\n3. **Conduct Research**\n   \n   When user requests research on a topic:\n   \n   - Search for relevant information\n   - Find credible sources\n   - Extract key facts, quotes, and data\n   - Add citations in requested format\n   \n   Example output:\n   ```markdown\n   ## Research: AI Impact on Productivity\n   \n   Key Findings:\n   \n   1. **Productivity Gains**: Studies show 40% time savings for \n      content creation tasks [1]\n   \n   2. **Adoption Rates**: 67% of knowledge workers use AI tools \n      weekly [2]\n   \n   3. **Expert Quote**: \"AI augments rather than replaces human \n      creativity\" - Dr. Jane Smith, MIT [3]\n   \n   Citations:\n   [1] McKinsey Global Institute. (2024). \"The Economic Potential \n       of Generative AI\"\n   [2] Stack Overflow Developer Survey (2024)\n   [3] Smith, J. (2024). MIT Technology Review interview\n   \n   Added to outline under Section 2.\n   ```\n\n4. **Improve Hooks**\n   \n   When user shares an introduction, analyze and strengthen:\n   \n   **Current Hook Analysis**:\n   - What works: [positive elements]\n   - What could be stronger: [areas for improvement]\n   - Emotional impact: [current vs. potential]\n   \n   **Suggested Alternatives**:\n   \n   Option 1: [Bold statement]\n   > [Example]\n   *Why it works: [explanation]*\n   \n   Option 2: [Personal story]\n   > [Example]\n   *Why it works: [explanation]*\n   \n   Option 3: [Surprising data]\n   > [Example]\n   *Why it works: [explanation]*\n   \n   **Questions to hook**:\n   - Does it create curiosity?\n   - Does it promise value?\n   - Is it specific enough?\n   - Does it match the audience?\n\n5. **Provide Section-by-Section Feedback**\n   \n   As user writes each section, review for:\n   \n   ```markdown\n   # Feedback: [Section Name]\n   \n   ## What Works Well ✓\n   - [Strength 1]\n   - [Strength 2]\n   - [Strength 3]\n   \n   ## Suggestions for Improvement\n   \n   ### Clarity\n   - [Specific issue] → [Suggested fix]\n   - [Complex sentence] → [Simpler alternative]\n   \n   ### Flow\n   - [Transition issue] → [Better connection]\n   - [Paragraph order] → [Suggested reordering]\n   \n   ### Evidence\n   - [Claim needing support] → [Add citation or example]\n   - [Generic statement] → [Make more specific]\n   \n   ### Style\n   - [Tone inconsistency] → [Match your voice better]\n   - [Word choice] → [Stronger alternative]\n   \n   ## Specific Line Edits\n   \n   Original:\n   > [Exact quote from draft]\n   \n   Suggested:\n   > [Improved version]\n   \n   Why: [Explanation]\n   \n   ## Questions to Consider\n   - [Thought-provoking question 1]\n   - [Thought-provoking question 2]\n   \n   Ready to move to next section!\n   ```\n\n6. **Preserve Writer's Voice**\n   \n   Important principles:\n   \n   - **Learn their style**: Read existing writing samples\n   - **Suggest, don't replace**: Offer options, not directives\n   - **Match tone**: Formal, casual, technical, friendly\n   - **Respect choices**: If they prefer their version, support it\n   - **Enhance, don't override**: Make their writing better, not different\n   \n   Ask periodically:\n   - \"Does this sound like you?\"\n   - \"Is this the right tone?\"\n   - \"Should I be more/less [formal/casual/technical]?\"\n\n7. **Citation Management**\n   \n   Handle references based on user preference:\n   \n   **Inline Citations**:\n   ```markdown\n   Studies show 40% productivity improvement (McKinsey, 2024).\n   ```\n   \n   **Numbered References**:\n   ```markdown\n   Studies show 40% productivity improvement [1].\n   \n   [1] McKinsey Global Institute. (2024)...\n   ```\n   \n   **Footnote Style**:\n   ```markdown\n   Studies show 40% productivity improvement^1\n   \n   ^1: McKinsey Global Institute. (2024)...\n   ```\n   \n   Maintain a running citations list:\n   ```markdown\n   ## References\n   \n   1. Author. (Year). \"Title\". Publication.\n   2. Author. (Year). \"Title\". Publication.\n   ...\n   ```\n\n8. **Final Review and Polish**\n   \n   When draft is complete, provide comprehensive feedback:\n   \n   ```markdown\n   # Full Draft Review\n   \n   ## Overall Assessment\n   \n   **Strengths**:\n   - [Major strength 1]\n   - [Major strength 2]\n   - [Major strength 3]\n   \n   **Impact**: [Overall effectiveness assessment]\n   \n   ## Structure & Flow\n   - [Comments on organization]\n   - [Transition quality]\n   - [Pacing assessment]\n   \n   ## Content Quality\n   - [Argument strength]\n   - [Evidence sufficiency]\n   - [Example effectiveness]\n   \n   ## Technical Quality\n   - Grammar and mechanics: [assessment]\n   - Consistency: [assessment]\n   - Citations: [completeness check]\n   \n   ## Readability\n   - Clarity score: [evaluation]\n   - Sentence variety: [evaluation]\n   - Paragraph length: [evaluation]\n   \n   ## Final Polish Suggestions\n   \n   1. **Introduction**: [Specific improvements]\n   2. **Body**: [Specific improvements]\n   3. **Conclusion**: [Specific improvements]\n   4. **Title**: [Options if needed]\n   \n   ## Pre-Publish Checklist\n   - [ ] All claims sourced\n   - [ ] Citations formatted\n   - [ ] Examples clear\n   - [ ] Transitions smooth\n   - [ ] Call to action present\n   - [ ] Proofread for typos\n   \n   Ready to publish! 🚀\n   ```\n\n## Examples\n\n### Example 1: Teresa Torres's Workflow\n\n**User**: \"I'm writing an article about continuous discovery. Help me create an outline.\"\n\n**Process**:\n1. Collaborates on outline structure\n2. Identifies research needs\n3. User starts writing introduction\n4. Reviews and improves the hook\n5. User writes each section\n6. Provides feedback after each section\n7. Conducts research and adds citations\n8. Final review of complete draft\n9. Polish and prep for publishing\n\n**Result**: Well-researched, properly cited article written in Teresa's voice with strong structure and flow.\n\n### Example 2: Research-Heavy Article\n\n**User**: \"I'm writing about AI's impact on product management. Help me find current data and examples.\"\n\n**Output**:\n```markdown\n## Research Compiled\n\n### Recent Data\n- Gartner: 80% of PMs will use AI tools by 2025 [1]\n- Survey: 45% report faster feature shipping [2]\n- Case study: Airbnb's AI-assisted prioritization [3]\n\n### Expert Quotes\n- \"AI amplifies PM judgment, not replaces it\" - Marty Cagan\n- [Additional quotes with citations]\n\n### Real Examples\n1. **Company A**: Used AI for user research synthesis\n   - Result: 60% time savings\n   - Source: [citation]\n\n2. **Company B**: AI-powered roadmap analysis\n   - Result: Better stakeholder alignment\n   - Source: [citation]\n\nAll added to your outline with proper citations.\n```\n\n### Example 3: Hook Improvement\n\n**User's Original Hook**:\n> \"Product management is changing because of AI. In this article, I'll discuss some ways AI affects product managers.\"\n\n**Improved Options**:\n\n**Option 1 (Data-driven)**:\n> \"Last month, I asked AI to analyze 500 customer interviews. It took 30 minutes instead of 3 weeks. Product management will never be the same.\"\n\n**Option 2 (Question)**:\n> \"What if you could talk to every customer, read every review, and analyze every support ticket—all before your morning coffee?\"\n\n**Option 3 (Story)**:\n> \"Sarah spent two weeks building the wrong feature. Not because she didn't understand her users, but because she couldn't process the hundreds of interviews fast enough to spot the pattern.\"\n\n### Example 4: Section Feedback\n\n**User**: \"Just finished my 'Common Mistakes' section. Thoughts?\"\n\n**Response**:\n```markdown\n# Feedback: Common Mistakes Section\n\n## What Works Well ✓\n- Strong examples (the Slack notification story)\n- Clear structure (3 mistakes, clean layout)\n- Practical advice for each mistake\n\n## Suggestions\n\n### Make It More Specific\nYour second point says \"Bad prioritization\" but could be stronger:\n\nCurrent:\n> \"Many teams prioritize badly by focusing on features instead of outcomes.\"\n\nSuggested:\n> \"I've watched teams ship 14 features in a quarter yet move none of their key metrics. They prioritized activity over progress.\"\n\n### Add Data\nThe third mistake would benefit from evidence:\n> \"[Add citation]: Studies show teams without regular user contact are 3x more likely to build unused features [needs source]\"\n\n### Flow Improvement\nConsider reordering: Mistake 3 → Mistake 2 → Mistake 1\nThis builds from small to big impact.\n\nReady for the next section!\n```\n\n## Writing Workflows\n\n### Blog Post Workflow\n1. Outline together\n2. Research key points\n3. Write introduction → get feedback\n4. Write body sections → feedback each\n5. Write conclusion → final review\n6. Polish and edit\n\n### Newsletter Workflow\n1. Discuss hook ideas\n2. Quick outline (shorter format)\n3. Draft in one session\n4. Review for clarity and links\n5. Quick polish\n\n### Technical Tutorial Workflow\n1. Outline steps\n2. Write code examples\n3. Add explanations\n4. Test instructions\n5. Add troubleshooting section\n6. Final review for accuracy\n\n### Thought Leadership Workflow\n1. Brainstorm unique angle\n2. Research existing perspectives\n3. Develop your thesis\n4. Write with strong POV\n5. Add supporting evidence\n6. Craft compelling conclusion\n\n## Pro Tips\n\n1. **Work in VS Code**: Better than web Claude for long-form writing\n2. **One section at a time**: Get feedback incrementally\n3. **Save research separately**: Keep a research.md file\n4. **Version your drafts**: article-v1.md, article-v2.md, etc.\n5. **Read aloud**: Use feedback to identify clunky sentences\n6. **Set deadlines**: \"I want to finish the draft today\"\n7. **Take breaks**: Write, get feedback, pause, revise\n\n## File Organization\n\nRecommended structure for writing projects:\n\n```\n~/writing/article-name/\n├── outline.md          # Your outline\n├── research.md         # All research and citations\n├── draft-v1.md         # First draft\n├── draft-v2.md         # Revised draft\n├── final.md            # Publication-ready\n├── feedback.md         # Collected feedback\n└── sources/            # Reference materials\n    ├── study1.pdf\n    └── article2.md\n```\n\n## Best Practices\n\n### For Research\n- Verify sources before citing\n- Use recent data when possible\n- Balance different perspectives\n- Link to original sources\n\n### For Feedback\n- Be specific about what you want: \"Is this too technical?\"\n- Share your concerns: \"I'm worried this section drags\"\n- Ask questions: \"Does this flow logically?\"\n- Request alternatives: \"What's another way to explain this?\"\n\n### For Voice\n- Share examples of your writing\n- Specify tone preferences\n- Point out good matches: \"That sounds like me!\"\n- Flag mismatches: \"Too formal for my style\"\n\n## Related Use Cases\n\n- Creating social media posts from articles\n- Adapting content for different audiences\n- Writing email newsletters\n- Drafting technical documentation\n- Creating presentation content\n- Writing case studies\n- Developing course outlines\n\n"
  },
  {
    "path": "developer-growth-analysis/SKILL.md",
    "content": "---\nname: developer-growth-analysis\ndescription: Analyzes your recent Claude Code chat history to identify coding patterns, development gaps, and areas for improvement, curates relevant learning resources from HackerNews, and automatically sends a personalized growth report to your Slack DMs.\n---\n\n# Developer Growth Analysis\n\nThis skill provides personalized feedback on your recent coding work by analyzing your Claude Code chat interactions and identifying patterns that reveal strengths and areas for growth.\n\n## When to Use This Skill\n\nUse this skill when you want to:\n- Understand your development patterns and habits from recent work\n- Identify specific technical gaps or recurring challenges\n- Discover which topics would benefit from deeper study\n- Get curated learning resources tailored to your actual work patterns\n- Track improvement areas across your recent projects\n- Find high-quality articles that directly address the skills you're developing\n\nThis skill is ideal for developers who want structured feedback on their growth without waiting for code reviews, and who prefer data-driven insights from their own work history.\n\n## What This Skill Does\n\nThis skill performs a six-step analysis of your development work:\n\n1. **Reads Your Chat History**: Accesses your local Claude Code chat history from the past 24-48 hours to understand what you've been working on.\n\n2. **Identifies Development Patterns**: Analyzes the types of problems you're solving, technologies you're using, challenges you encounter, and how you approach different kinds of tasks.\n\n3. **Detects Improvement Areas**: Recognizes patterns that suggest skill gaps, repeated struggles, inefficient approaches, or areas where you might benefit from deeper knowledge.\n\n4. **Generates a Personalized Report**: Creates a comprehensive report showing your work summary, identified improvement areas, and specific recommendations for growth.\n\n5. **Finds Learning Resources**: Uses HackerNews to curate high-quality articles and discussions directly relevant to your improvement areas, providing you with a reading list tailored to your actual development work.\n\n6. **Sends to Your Slack DMs**: Automatically delivers the complete report to your own Slack direct messages so you can reference it anytime, anywhere.\n\n## How to Use\n\nAsk Claude to analyze your recent coding work:\n\n```\nAnalyze my developer growth from my recent chats\n```\n\nOr be more specific about which time period:\n\n```\nAnalyze my work from today and suggest areas for improvement\n```\n\nThe skill will generate a formatted report with:\n- Overview of your recent work\n- Key improvement areas identified\n- Specific recommendations for each area\n- Curated learning resources from HackerNews\n- Action items you can focus on\n\n## Instructions\n\nWhen a user requests analysis of their developer growth or coding patterns from recent work:\n\n1. **Access Chat History**\n\n   Read the chat history from `~/.claude/history.jsonl`. This file is a JSONL format where each line contains:\n   - `display`: The user's message/request\n   - `project`: The project being worked on\n   - `timestamp`: Unix timestamp (in milliseconds)\n   - `pastedContents`: Any code or content pasted\n\n   Filter for entries from the past 24-48 hours based on the current timestamp.\n\n2. **Analyze Work Patterns**\n\n   Extract and analyze the following from the filtered chats:\n   - **Projects and Domains**: What types of projects was the user working on? (e.g., backend, frontend, DevOps, data, etc.)\n   - **Technologies Used**: What languages, frameworks, and tools appear in the conversations?\n   - **Problem Types**: What categories of problems are being solved? (e.g., performance optimization, debugging, feature implementation, refactoring, setup/configuration)\n   - **Challenges Encountered**: What problems did the user struggle with? Look for:\n     - Repeated questions about similar topics\n     - Problems that took multiple attempts to solve\n     - Questions indicating knowledge gaps\n     - Complex architectural decisions\n   - **Approach Patterns**: How does the user solve problems? (e.g., methodical, exploratory, experimental)\n\n3. **Identify Improvement Areas**\n\n   Based on the analysis, identify 3-5 specific areas where the user could improve. These should be:\n   - **Specific** (not vague like \"improve coding skills\")\n   - **Evidence-based** (grounded in actual chat history)\n   - **Actionable** (practical improvements that can be made)\n   - **Prioritized** (most impactful first)\n\n   Examples of good improvement areas:\n   - \"Advanced TypeScript patterns (generics, utility types, type guards) - you struggled with type safety in [specific project]\"\n   - \"Error handling and validation - I noticed you patched several bugs related to missing null checks\"\n   - \"Async/await patterns - your recent work shows some race conditions and timing issues\"\n   - \"Database query optimization - you rewrote the same query multiple times\"\n\n4. **Generate Report**\n\n   Create a comprehensive report with this structure:\n\n   ```markdown\n   # Your Developer Growth Report\n\n   **Report Period**: [Yesterday / Today / [Custom Date Range]]\n   **Last Updated**: [Current Date and Time]\n\n   ## Work Summary\n\n   [2-3 paragraphs summarizing what the user worked on, projects touched, technologies used, and overall focus areas]\n\n   Example:\n   \"Over the past 24 hours, you focused primarily on backend development with three distinct projects. Your work involved TypeScript, React, and deployment infrastructure. You tackled a mix of feature implementation, debugging, and architectural decisions, with a particular focus on API design and database optimization.\"\n\n   ## Improvement Areas (Prioritized)\n\n   ### 1. [Area Name]\n\n   **Why This Matters**: [Explanation of why this skill is important for the user's work]\n\n   **What I Observed**: [Specific evidence from chat history showing this gap]\n\n   **Recommendation**: [Concrete step(s) to improve in this area]\n\n   **Time to Skill Up**: [Brief estimate of effort required]\n\n   ---\n\n   [Repeat for 2-4 additional areas]\n\n   ## Strengths Observed\n\n   [2-3 bullet points highlighting things you're doing well - things to continue doing]\n\n   ## Action Items\n\n   Priority order:\n   1. [Action item derived from highest priority improvement area]\n   2. [Action item from next area]\n   3. [Action item from next area]\n\n   ## Learning Resources\n\n   [Will be populated in next step]\n   ```\n\n5. **Search for Learning Resources**\n\n   Use Rube MCP to search HackerNews for articles related to each improvement area:\n\n   - For each improvement area, construct a search query targeting high-quality resources\n   - Search HackerNews using RUBE_SEARCH_TOOLS with queries like:\n     - \"Learn [Technology/Pattern] best practices\"\n     - \"[Technology] advanced patterns and techniques\"\n     - \"Debugging [specific problem type] in [language]\"\n   - Prioritize posts with high engagement (comments, upvotes)\n   - For each area, include 2-3 most relevant articles with:\n     - Article title\n     - Publication date\n     - Brief description of why it's relevant\n     - Link to the article\n\n   Add this section to the report:\n\n   ```markdown\n   ## Curated Learning Resources\n\n   ### For: [Improvement Area]\n\n   1. **[Article Title]** - [Date]\n      [Description of what it covers and why it's relevant to your improvement area]\n      [Link]\n\n   2. **[Article Title]** - [Date]\n      [Description]\n      [Link]\n\n   [Repeat for other improvement areas]\n   ```\n\n6. **Present the Complete Report**\n\n   Deliver the report in a clean, readable format that the user can:\n   - Quickly scan for key takeaways\n   - Use for focused learning planning\n   - Reference over the next week as they work on improvements\n   - Share with mentors if they want external feedback\n\n7. **Send Report to Slack DMs**\n\n   Use Rube MCP to send the complete report to the user's own Slack DMs:\n\n   - Check if Slack connection is active via RUBE_SEARCH_TOOLS\n   - If not connected, use RUBE_MANAGE_CONNECTIONS to initiate Slack auth\n   - Use RUBE_MULTI_EXECUTE_TOOL to send the report as a formatted message:\n     - Send the report title and period as the first message\n     - Break the report into logical sections (Summary, Improvements, Strengths, Actions, Resources)\n     - Format each section as a well-structured Slack message with proper markdown\n     - Include clickable links for the learning resources\n   - Confirm delivery in the CLI output\n\n   This ensures the user has the report in a place they check regularly and can reference it throughout the week.\n\n## Example Usage\n\n### Input\n\n```\nAnalyze my developer growth from my recent chats\n```\n\n### Output\n\n```markdown\n# Your Developer Growth Report\n\n**Report Period**: November 9-10, 2024\n**Last Updated**: November 10, 2024, 9:15 PM UTC\n\n## Work Summary\n\nOver the past two days, you focused on backend infrastructure and API development. Your primary project was an open-source showcase application, where you made significant progress on connections management, UI improvements, and deployment configuration. You worked with TypeScript, React, and Node.js, tackling challenges ranging from data security to responsive design. Your work shows a balance between implementing features and addressing technical debt.\n\n## Improvement Areas (Prioritized)\n\n### 1. Advanced TypeScript Patterns and Type Safety\n\n**Why This Matters**: TypeScript is central to your work, but leveraging its advanced features (generics, utility types, conditional types, type guards) can significantly improve code reliability and reduce runtime errors. Better type safety catches bugs at compile time rather than in production.\n\n**What I Observed**: In your recent chats, you were working with connection data structures and struggled a few times with typing auth configurations properly. You also had to iterate on union types for different connection states. There's an opportunity to use discriminated unions and type guards more effectively.\n\n**Recommendation**: Study TypeScript's advanced type system, particularly utility types (Omit, Pick, Record), conditional types, and discriminated unions. Apply these patterns to your connection configuration handling and auth state management.\n\n**Time to Skill Up**: 5-8 hours of focused learning and practice\n\n### 2. Secure Data Handling and Information Hiding in UI\n\n**Why This Matters**: You identified and fixed a security concern where sensitive connection data was being displayed in your console. Preventing information leakage is critical for applications handling user credentials and API keys. Good practices here prevent security incidents and user trust violations.\n\n**What I Observed**: You caught that your \"Your Apps\" page was showing full connection data including auth configs. This shows good security instincts, and the next step is building this into your default thinking when handling sensitive information.\n\n**Recommendation**: Review security best practices for handling sensitive data in frontend applications. Create reusable patterns for filtering/masking sensitive information before displaying it. Consider implementing a secure data layer that explicitly whitelist what can be shown in the UI.\n\n**Time to Skill Up**: 3-4 hours\n\n### 3. Component Architecture and Responsive UI Patterns\n\n**Why This Matters**: You're designing UIs that need to work across different screen sizes and user interactions. Strong component architecture makes it easier to build complex UIs without bugs and improves maintainability.\n\n**What I Observed**: You worked on the \"Marketplace\" UI (formerly Browse Tools), recreating it from a design image. You also identified and fixed scrolling issues where content was overflowing containers. There's an opportunity to strengthen your understanding of layout containment and responsive design patterns.\n\n**Recommendation**: Study React component composition patterns and CSS layout best practices (especially flexbox and grid). Focus on container queries and responsive patterns that prevent overflow issues. Look into component composition libraries and design system approaches.\n\n**Time to Skill Up**: 6-10 hours (depending on depth)\n\n## Strengths Observed\n\n- **Security Awareness**: You proactively identified data leakage issues before they became problems\n- **Iterative Refinement**: You worked through UI requirements methodically, asking clarifying questions and improving designs\n- **Full-Stack Capability**: You comfortably work across backend APIs, frontend UI, and deployment concerns\n- **Problem-Solving Approach**: You break down complex tasks into manageable steps\n\n## Action Items\n\nPriority order:\n1. Spend 1-2 hours learning TypeScript utility types and discriminated unions; apply to your connection data structures\n2. Document security patterns for your project (what data is safe to display, filtering/masking functions)\n3. Study one article on advanced React patterns and apply one pattern to your current UI work\n4. Set up a code review checklist focused on type safety and data security for future PRs\n\n## Curated Learning Resources\n\n### For: Advanced TypeScript Patterns\n\n1. **TypeScript's Advanced Types: Generics, Utility Types, and Conditional Types** - HackerNews, October 2024\n   Deep dive into TypeScript's type system with practical examples and real-world applications. Covers discriminated unions, type guards, and patterns for ensuring compile-time safety in complex applications.\n   [Link to discussion]\n\n2. **Building Type-Safe APIs in TypeScript** - HackerNews, September 2024\n   Practical guide to designing APIs with TypeScript that catch errors early. Particularly relevant for your connection configuration work.\n   [Link to discussion]\n\n### For: Secure Data Handling in Frontend\n\n1. **Preventing Information Leakage in Web Applications** - HackerNews, August 2024\n   Comprehensive guide to data security in frontend applications, including filtering sensitive information, secure logging, and audit trails.\n   [Link to discussion]\n\n2. **OAuth and API Key Management Best Practices** - HackerNews, July 2024\n   How to safely handle authentication tokens and API keys in applications, with examples for different frameworks.\n   [Link to discussion]\n\n### For: Component Architecture and Responsive Design\n\n1. **Advanced React Patterns: Composition Over Configuration** - HackerNews\n   Explores component composition strategies that scale, with examples using modern React patterns.\n   [Link to discussion]\n\n2. **CSS Layout Mastery: Flexbox, Grid, and Container Queries** - HackerNews, October 2024\n   Learn responsive design patterns that prevent overflow issues and work across all screen sizes.\n   [Link to discussion]\n```\n\n## Tips and Best Practices\n\n- Run this analysis once a week to track your improvement trajectory over time\n- Pick one improvement area at a time and focus on it for a few days before moving to the next\n- Use the learning resources as a study guide; work through the recommended materials and practice applying the patterns\n- Revisit this report after focusing on an area for a week to see how your work patterns change\n- The learning resources are intentionally curated for your actual work, not generic topics, so they'll be highly relevant to what you're building\n\n## How Accuracy and Quality Are Maintained\n\nThis skill:\n- Analyzes your actual work patterns from timestamped chat history\n- Generates evidence-based recommendations grounded in real projects\n- Curates learning resources that directly address your identified gaps\n- Focuses on actionable improvements, not vague feedback\n- Provides specific time estimates based on complexity\n- Prioritizes areas that will have the most impact on your development velocity\n"
  },
  {
    "path": "document-skills/docx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "document-skills/docx/SKILL.md",
    "content": "---\nname: docx\ndescription: \"Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# DOCX creation, editing, and analysis\n\n## Overview\n\nA user may ask you to create, edit, or analyze the contents of a .docx file. A .docx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.\n\n## Workflow Decision Tree\n\n### Reading/Analyzing Content\nUse \"Text extraction\" or \"Raw XML access\" sections below\n\n### Creating New Document\nUse \"Creating a new Word document\" workflow\n\n### Editing Existing Document\n- **Your own document + simple changes**\n  Use \"Basic OOXML editing\" workflow\n\n- **Someone else's document**\n  Use **\"Redlining workflow\"** (recommended default)\n\n- **Legal, academic, business, or government docs**\n  Use **\"Redlining workflow\"** (required)\n\n## Reading and analyzing content\n\n### Text extraction\nIf you just need to read the text contents of a document, you should convert the document to markdown using pandoc. Pandoc provides excellent support for preserving document structure and can show tracked changes:\n\n```bash\n# Convert document to markdown with tracked changes\npandoc --track-changes=all path-to-file.docx -o output.md\n# Options: --track-changes=accept/reject/all\n```\n\n### Raw XML access\nYou need raw XML access for: comments, complex formatting, document structure, embedded media, and metadata. For any of these features, you'll need to unpack a document and read its raw XML contents.\n\n#### Unpacking a file\n`python ooxml/scripts/unpack.py <office_file> <output_directory>`\n\n#### Key file structures\n* `word/document.xml` - Main document contents\n* `word/comments.xml` - Comments referenced in document.xml\n* `word/media/` - Embedded images and media files\n* Tracked changes use `<w:ins>` (insertions) and `<w:del>` (deletions) tags\n\n## Creating a new Word document\n\nWhen creating a new Word document from scratch, use **docx-js**, which allows you to create Word documents using JavaScript/TypeScript.\n\n### Workflow\n1. **MANDATORY - READ ENTIRE FILE**: Read [`docx-js.md`](docx-js.md) (~500 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Read the full file content for detailed syntax, critical formatting rules, and best practices before proceeding with document creation.\n2. Create a JavaScript/TypeScript file using Document, Paragraph, TextRun components (You can assume all dependencies are installed, but if not, refer to the dependencies section below)\n3. Export as .docx using Packer.toBuffer()\n\n## Editing an existing Word document\n\nWhen editing an existing Word document, use the **Document library** (a Python library for OOXML manipulation). The library automatically handles infrastructure setup and provides methods for document manipulation. For complex scenarios, you can access the underlying DOM directly through the library.\n\n### Workflow\n1. **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~600 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Read the full file content for the Document library API and XML patterns for directly editing document files.\n2. Unpack the document: `python ooxml/scripts/unpack.py <office_file> <output_directory>`\n3. Create and run a Python script using the Document library (see \"Document Library\" section in ooxml.md)\n4. Pack the final document: `python ooxml/scripts/pack.py <input_directory> <office_file>`\n\nThe Document library provides both high-level methods for common operations and direct DOM access for complex scenarios.\n\n## Redlining workflow for document review\n\nThis workflow allows you to plan comprehensive tracked changes using markdown before implementing them in OOXML. **CRITICAL**: For complete tracked changes, you must implement ALL changes systematically.\n\n**Batching Strategy**: Group related changes into batches of 3-10 changes. This makes debugging manageable while maintaining efficiency. Test each batch before moving to the next.\n\n**Principle: Minimal, Precise Edits**\nWhen implementing tracked changes, only mark text that actually changes. Repeating unchanged text makes edits harder to review and appears unprofessional. Break replacements into: [unchanged text] + [deletion] + [insertion] + [unchanged text]. Preserve the original run's RSID for unchanged text by extracting the `<w:r>` element from the original and reusing it.\n\nExample - Changing \"30 days\" to \"60 days\" in a sentence:\n```python\n# BAD - Replaces entire sentence\n'<w:del><w:r><w:delText>The term is 30 days.</w:delText></w:r></w:del><w:ins><w:r><w:t>The term is 60 days.</w:t></w:r></w:ins>'\n\n# GOOD - Only marks what changed, preserves original <w:r> for unchanged text\n'<w:r w:rsidR=\"00AB12CD\"><w:t>The term is </w:t></w:r><w:del><w:r><w:delText>30</w:delText></w:r></w:del><w:ins><w:r><w:t>60</w:t></w:r></w:ins><w:r w:rsidR=\"00AB12CD\"><w:t> days.</w:t></w:r>'\n```\n\n### Tracked changes workflow\n\n1. **Get markdown representation**: Convert document to markdown with tracked changes preserved:\n   ```bash\n   pandoc --track-changes=all path-to-file.docx -o current.md\n   ```\n\n2. **Identify and group changes**: Review the document and identify ALL changes needed, organizing them into logical batches:\n\n   **Location methods** (for finding changes in XML):\n   - Section/heading numbers (e.g., \"Section 3.2\", \"Article IV\")\n   - Paragraph identifiers if numbered\n   - Grep patterns with unique surrounding text\n   - Document structure (e.g., \"first paragraph\", \"signature block\")\n   - **DO NOT use markdown line numbers** - they don't map to XML structure\n\n   **Batch organization** (group 3-10 related changes per batch):\n   - By section: \"Batch 1: Section 2 amendments\", \"Batch 2: Section 5 updates\"\n   - By type: \"Batch 1: Date corrections\", \"Batch 2: Party name changes\"\n   - By complexity: Start with simple text replacements, then tackle complex structural changes\n   - Sequential: \"Batch 1: Pages 1-3\", \"Batch 2: Pages 4-6\"\n\n3. **Read documentation and unpack**:\n   - **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~600 lines) completely from start to finish. **NEVER set any range limits when reading this file.** Pay special attention to the \"Document Library\" and \"Tracked Change Patterns\" sections.\n   - **Unpack the document**: `python ooxml/scripts/unpack.py <file.docx> <dir>`\n   - **Note the suggested RSID**: The unpack script will suggest an RSID to use for your tracked changes. Copy this RSID for use in step 4b.\n\n4. **Implement changes in batches**: Group changes logically (by section, by type, or by proximity) and implement them together in a single script. This approach:\n   - Makes debugging easier (smaller batch = easier to isolate errors)\n   - Allows incremental progress\n   - Maintains efficiency (batch size of 3-10 changes works well)\n\n   **Suggested batch groupings:**\n   - By document section (e.g., \"Section 3 changes\", \"Definitions\", \"Termination clause\")\n   - By change type (e.g., \"Date changes\", \"Party name updates\", \"Legal term replacements\")\n   - By proximity (e.g., \"Changes on pages 1-3\", \"Changes in first half of document\")\n\n   For each batch of related changes:\n\n   **a. Map text to XML**: Grep for text in `word/document.xml` to verify how text is split across `<w:r>` elements.\n\n   **b. Create and run script**: Use `get_node` to find nodes, implement changes, then `doc.save()`. See **\"Document Library\"** section in ooxml.md for patterns.\n\n   **Note**: Always grep `word/document.xml` immediately before writing a script to get current line numbers and verify text content. Line numbers change after each script run.\n\n5. **Pack the document**: After all batches are complete, convert the unpacked directory back to .docx:\n   ```bash\n   python ooxml/scripts/pack.py unpacked reviewed-document.docx\n   ```\n\n6. **Final verification**: Do a comprehensive check of the complete document:\n   - Convert final document to markdown:\n     ```bash\n     pandoc --track-changes=all reviewed-document.docx -o verification.md\n     ```\n   - Verify ALL changes were applied correctly:\n     ```bash\n     grep \"original phrase\" verification.md  # Should NOT find it\n     grep \"replacement phrase\" verification.md  # Should find it\n     ```\n   - Check that no unintended changes were introduced\n\n\n## Converting Documents to Images\n\nTo visually analyze Word documents, convert them to images using a two-step process:\n\n1. **Convert DOCX to PDF**:\n   ```bash\n   soffice --headless --convert-to pdf document.docx\n   ```\n\n2. **Convert PDF pages to JPEG images**:\n   ```bash\n   pdftoppm -jpeg -r 150 document.pdf page\n   ```\n   This creates files like `page-1.jpg`, `page-2.jpg`, etc.\n\nOptions:\n- `-r 150`: Sets resolution to 150 DPI (adjust for quality/size balance)\n- `-jpeg`: Output JPEG format (use `-png` for PNG if preferred)\n- `-f N`: First page to convert (e.g., `-f 2` starts from page 2)\n- `-l N`: Last page to convert (e.g., `-l 5` stops at page 5)\n- `page`: Prefix for output files\n\nExample for specific range:\n```bash\npdftoppm -jpeg -r 150 -f 2 -l 5 document.pdf page  # Converts only pages 2-5\n```\n\n## Code Style Guidelines\n**IMPORTANT**: When generating code for DOCX operations:\n- Write concise code\n- Avoid verbose variable names and redundant operations\n- Avoid unnecessary print statements\n\n## Dependencies\n\nRequired dependencies (install if not available):\n\n- **pandoc**: `sudo apt-get install pandoc` (for text extraction)\n- **docx**: `npm install -g docx` (for creating new documents)\n- **LibreOffice**: `sudo apt-get install libreoffice` (for PDF conversion)\n- **Poppler**: `sudo apt-get install poppler-utils` (for pdftoppm to convert PDF to images)\n- **defusedxml**: `pip install defusedxml` (for secure XML parsing)"
  },
  {
    "path": "document-skills/docx/docx-js.md",
    "content": "# DOCX Library Tutorial\n\nGenerate .docx files with JavaScript/TypeScript.\n\n**Important: Read this entire document before starting.** Critical formatting rules and common pitfalls are covered throughout - skipping sections may result in corrupted files or rendering issues.\n\n## Setup\nAssumes docx is already installed globally\nIf not installed: `npm install -g docx`\n\n```javascript\nconst { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun, Media, \n        Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink, \n        InternalHyperlink, TableOfContents, HeadingLevel, BorderStyle, WidthType, TabStopType, \n        TabStopPosition, UnderlineType, ShadingType, VerticalAlign, SymbolRun, PageNumber,\n        FootnoteReferenceRun, Footnote, PageBreak } = require('docx');\n\n// Create & Save\nconst doc = new Document({ sections: [{ children: [/* content */] }] });\nPacker.toBuffer(doc).then(buffer => fs.writeFileSync(\"doc.docx\", buffer)); // Node.js\nPacker.toBlob(doc).then(blob => { /* download logic */ }); // Browser\n```\n\n## Text & Formatting\n```javascript\n// IMPORTANT: Never use \\n for line breaks - always use separate Paragraph elements\n// ❌ WRONG: new TextRun(\"Line 1\\nLine 2\")\n// ✅ CORRECT: new Paragraph({ children: [new TextRun(\"Line 1\")] }), new Paragraph({ children: [new TextRun(\"Line 2\")] })\n\n// Basic text with all formatting options\nnew Paragraph({\n  alignment: AlignmentType.CENTER,\n  spacing: { before: 200, after: 200 },\n  indent: { left: 720, right: 720 },\n  children: [\n    new TextRun({ text: \"Bold\", bold: true }),\n    new TextRun({ text: \"Italic\", italics: true }),\n    new TextRun({ text: \"Underlined\", underline: { type: UnderlineType.DOUBLE, color: \"FF0000\" } }),\n    new TextRun({ text: \"Colored\", color: \"FF0000\", size: 28, font: \"Arial\" }), // Arial default\n    new TextRun({ text: \"Highlighted\", highlight: \"yellow\" }),\n    new TextRun({ text: \"Strikethrough\", strike: true }),\n    new TextRun({ text: \"x2\", superScript: true }),\n    new TextRun({ text: \"H2O\", subScript: true }),\n    new TextRun({ text: \"SMALL CAPS\", smallCaps: true }),\n    new SymbolRun({ char: \"2022\", font: \"Symbol\" }), // Bullet •\n    new SymbolRun({ char: \"00A9\", font: \"Arial\" })   // Copyright © - Arial for symbols\n  ]\n})\n```\n\n## Styles & Professional Formatting\n\n```javascript\nconst doc = new Document({\n  styles: {\n    default: { document: { run: { font: \"Arial\", size: 24 } } }, // 12pt default\n    paragraphStyles: [\n      // Document title style - override built-in Title style\n      { id: \"Title\", name: \"Title\", basedOn: \"Normal\",\n        run: { size: 56, bold: true, color: \"000000\", font: \"Arial\" },\n        paragraph: { spacing: { before: 240, after: 120 }, alignment: AlignmentType.CENTER } },\n      // IMPORTANT: Override built-in heading styles by using their exact IDs\n      { id: \"Heading1\", name: \"Heading 1\", basedOn: \"Normal\", next: \"Normal\", quickFormat: true,\n        run: { size: 32, bold: true, color: \"000000\", font: \"Arial\" }, // 16pt\n        paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // Required for TOC\n      { id: \"Heading2\", name: \"Heading 2\", basedOn: \"Normal\", next: \"Normal\", quickFormat: true,\n        run: { size: 28, bold: true, color: \"000000\", font: \"Arial\" }, // 14pt\n        paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },\n      // Custom styles use your own IDs\n      { id: \"myStyle\", name: \"My Style\", basedOn: \"Normal\",\n        run: { size: 28, bold: true, color: \"000000\" },\n        paragraph: { spacing: { after: 120 }, alignment: AlignmentType.CENTER } }\n    ],\n    characterStyles: [{ id: \"myCharStyle\", name: \"My Char Style\",\n      run: { color: \"FF0000\", bold: true, underline: { type: UnderlineType.SINGLE } } }]\n  },\n  sections: [{\n    properties: { page: { margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } } },\n    children: [\n      new Paragraph({ heading: HeadingLevel.TITLE, children: [new TextRun(\"Document Title\")] }), // Uses overridden Title style\n      new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun(\"Heading 1\")] }), // Uses overridden Heading1 style\n      new Paragraph({ style: \"myStyle\", children: [new TextRun(\"Custom paragraph style\")] }),\n      new Paragraph({ children: [\n        new TextRun(\"Normal with \"),\n        new TextRun({ text: \"custom char style\", style: \"myCharStyle\" })\n      ]})\n    ]\n  }]\n});\n```\n\n**Professional Font Combinations:**\n- **Arial (Headers) + Arial (Body)** - Most universally supported, clean and professional\n- **Times New Roman (Headers) + Arial (Body)** - Classic serif headers with modern sans-serif body\n- **Georgia (Headers) + Verdana (Body)** - Optimized for screen reading, elegant contrast\n\n**Key Styling Principles:**\n- **Override built-in styles**: Use exact IDs like \"Heading1\", \"Heading2\", \"Heading3\" to override Word's built-in heading styles\n- **HeadingLevel constants**: `HeadingLevel.HEADING_1` uses \"Heading1\" style, `HeadingLevel.HEADING_2` uses \"Heading2\" style, etc.\n- **Include outlineLevel**: Set `outlineLevel: 0` for H1, `outlineLevel: 1` for H2, etc. to ensure TOC works correctly\n- **Use custom styles** instead of inline formatting for consistency\n- **Set a default font** using `styles.default.document.run.font` - Arial is universally supported\n- **Establish visual hierarchy** with different font sizes (titles > headers > body)\n- **Add proper spacing** with `before` and `after` paragraph spacing\n- **Use colors sparingly**: Default to black (000000) and shades of gray for titles and headings (heading 1, heading 2, etc.)\n- **Set consistent margins** (1440 = 1 inch is standard)\n\n\n## Lists (ALWAYS USE PROPER LISTS - NEVER USE UNICODE BULLETS)\n```javascript\n// Bullets - ALWAYS use the numbering config, NOT unicode symbols\n// CRITICAL: Use LevelFormat.BULLET constant, NOT the string \"bullet\"\nconst doc = new Document({\n  numbering: {\n    config: [\n      { reference: \"bullet-list\",\n        levels: [{ level: 0, format: LevelFormat.BULLET, text: \"•\", alignment: AlignmentType.LEFT,\n          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },\n      { reference: \"first-numbered-list\",\n        levels: [{ level: 0, format: LevelFormat.DECIMAL, text: \"%1.\", alignment: AlignmentType.LEFT,\n          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },\n      { reference: \"second-numbered-list\", // Different reference = restarts at 1\n        levels: [{ level: 0, format: LevelFormat.DECIMAL, text: \"%1.\", alignment: AlignmentType.LEFT,\n          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }\n    ]\n  },\n  sections: [{\n    children: [\n      // Bullet list items\n      new Paragraph({ numbering: { reference: \"bullet-list\", level: 0 },\n        children: [new TextRun(\"First bullet point\")] }),\n      new Paragraph({ numbering: { reference: \"bullet-list\", level: 0 },\n        children: [new TextRun(\"Second bullet point\")] }),\n      // Numbered list items\n      new Paragraph({ numbering: { reference: \"first-numbered-list\", level: 0 },\n        children: [new TextRun(\"First numbered item\")] }),\n      new Paragraph({ numbering: { reference: \"first-numbered-list\", level: 0 },\n        children: [new TextRun(\"Second numbered item\")] }),\n      // ⚠️ CRITICAL: Different reference = INDEPENDENT list that restarts at 1\n      // Same reference = CONTINUES previous numbering\n      new Paragraph({ numbering: { reference: \"second-numbered-list\", level: 0 },\n        children: [new TextRun(\"Starts at 1 again (because different reference)\")] })\n    ]\n  }]\n});\n\n// ⚠️ CRITICAL NUMBERING RULE: Each reference creates an INDEPENDENT numbered list\n// - Same reference = continues numbering (1, 2, 3... then 4, 5, 6...)\n// - Different reference = restarts at 1 (1, 2, 3... then 1, 2, 3...)\n// Use unique reference names for each separate numbered section!\n\n// ⚠️ CRITICAL: NEVER use unicode bullets - they create fake lists that don't work properly\n// new TextRun(\"• Item\")           // WRONG\n// new SymbolRun({ char: \"2022\" }) // WRONG\n// ✅ ALWAYS use numbering config with LevelFormat.BULLET for real Word lists\n```\n\n## Tables\n```javascript\n// Complete table with margins, borders, headers, and bullet points\nconst tableBorder = { style: BorderStyle.SINGLE, size: 1, color: \"CCCCCC\" };\nconst cellBorders = { top: tableBorder, bottom: tableBorder, left: tableBorder, right: tableBorder };\n\nnew Table({\n  columnWidths: [4680, 4680], // ⚠️ CRITICAL: Set column widths at table level - values in DXA (twentieths of a point)\n  margins: { top: 100, bottom: 100, left: 180, right: 180 }, // Set once for all cells\n  rows: [\n    new TableRow({\n      tableHeader: true,\n      children: [\n        new TableCell({\n          borders: cellBorders,\n          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell\n          // ⚠️ CRITICAL: Always use ShadingType.CLEAR to prevent black backgrounds in Word.\n          shading: { fill: \"D5E8F0\", type: ShadingType.CLEAR }, \n          verticalAlign: VerticalAlign.CENTER,\n          children: [new Paragraph({ \n            alignment: AlignmentType.CENTER,\n            children: [new TextRun({ text: \"Header\", bold: true, size: 22 })]\n          })]\n        }),\n        new TableCell({\n          borders: cellBorders,\n          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell\n          shading: { fill: \"D5E8F0\", type: ShadingType.CLEAR },\n          children: [new Paragraph({ \n            alignment: AlignmentType.CENTER,\n            children: [new TextRun({ text: \"Bullet Points\", bold: true, size: 22 })]\n          })]\n        })\n      ]\n    }),\n    new TableRow({\n      children: [\n        new TableCell({\n          borders: cellBorders,\n          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell\n          children: [new Paragraph({ children: [new TextRun(\"Regular data\")] })]\n        }),\n        new TableCell({\n          borders: cellBorders,\n          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell\n          children: [\n            new Paragraph({ \n              numbering: { reference: \"bullet-list\", level: 0 },\n              children: [new TextRun(\"First bullet point\")] \n            }),\n            new Paragraph({ \n              numbering: { reference: \"bullet-list\", level: 0 },\n              children: [new TextRun(\"Second bullet point\")] \n            })\n          ]\n        })\n      ]\n    })\n  ]\n})\n```\n\n**IMPORTANT: Table Width & Borders**\n- Use BOTH `columnWidths: [width1, width2, ...]` array AND `width: { size: X, type: WidthType.DXA }` on each cell\n- Values in DXA (twentieths of a point): 1440 = 1 inch, Letter usable width = 9360 DXA (with 1\" margins)\n- Apply borders to individual `TableCell` elements, NOT the `Table` itself\n\n**Precomputed Column Widths (Letter size with 1\" margins = 9360 DXA total):**\n- **2 columns:** `columnWidths: [4680, 4680]` (equal width)\n- **3 columns:** `columnWidths: [3120, 3120, 3120]` (equal width)\n\n## Links & Navigation\n```javascript\n// TOC (requires headings) - CRITICAL: Use HeadingLevel only, NOT custom styles\n// ❌ WRONG: new Paragraph({ heading: HeadingLevel.HEADING_1, style: \"customHeader\", children: [new TextRun(\"Title\")] })\n// ✅ CORRECT: new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun(\"Title\")] })\nnew TableOfContents(\"Table of Contents\", { hyperlink: true, headingStyleRange: \"1-3\" }),\n\n// External link\nnew Paragraph({\n  children: [new ExternalHyperlink({\n    children: [new TextRun({ text: \"Google\", style: \"Hyperlink\" })],\n    link: \"https://www.google.com\"\n  })]\n}),\n\n// Internal link & bookmark\nnew Paragraph({\n  children: [new InternalHyperlink({\n    children: [new TextRun({ text: \"Go to Section\", style: \"Hyperlink\" })],\n    anchor: \"section1\"\n  })]\n}),\nnew Paragraph({\n  children: [new TextRun(\"Section Content\")],\n  bookmark: { id: \"section1\", name: \"section1\" }\n}),\n```\n\n## Images & Media\n```javascript\n// Basic image with sizing & positioning\n// CRITICAL: Always specify 'type' parameter - it's REQUIRED for ImageRun\nnew Paragraph({\n  alignment: AlignmentType.CENTER,\n  children: [new ImageRun({\n    type: \"png\", // NEW REQUIREMENT: Must specify image type (png, jpg, jpeg, gif, bmp, svg)\n    data: fs.readFileSync(\"image.png\"),\n    transformation: { width: 200, height: 150, rotation: 0 }, // rotation in degrees\n    altText: { title: \"Logo\", description: \"Company logo\", name: \"Name\" } // IMPORTANT: All three fields are required\n  })]\n})\n```\n\n## Page Breaks\n```javascript\n// Manual page break\nnew Paragraph({ children: [new PageBreak()] }),\n\n// Page break before paragraph\nnew Paragraph({\n  pageBreakBefore: true,\n  children: [new TextRun(\"This starts on a new page\")]\n})\n\n// ⚠️ CRITICAL: NEVER use PageBreak standalone - it will create invalid XML that Word cannot open\n// ❌ WRONG: new PageBreak() \n// ✅ CORRECT: new Paragraph({ children: [new PageBreak()] })\n```\n\n## Headers/Footers & Page Setup\n```javascript\nconst doc = new Document({\n  sections: [{\n    properties: {\n      page: {\n        margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }, // 1440 = 1 inch\n        size: { orientation: PageOrientation.LANDSCAPE },\n        pageNumbers: { start: 1, formatType: \"decimal\" } // \"upperRoman\", \"lowerRoman\", \"upperLetter\", \"lowerLetter\"\n      }\n    },\n    headers: {\n      default: new Header({ children: [new Paragraph({ \n        alignment: AlignmentType.RIGHT,\n        children: [new TextRun(\"Header Text\")]\n      })] })\n    },\n    footers: {\n      default: new Footer({ children: [new Paragraph({ \n        alignment: AlignmentType.CENTER,\n        children: [new TextRun(\"Page \"), new TextRun({ children: [PageNumber.CURRENT] }), new TextRun(\" of \"), new TextRun({ children: [PageNumber.TOTAL_PAGES] })]\n      })] })\n    },\n    children: [/* content */]\n  }]\n});\n```\n\n## Tabs\n```javascript\nnew Paragraph({\n  tabStops: [\n    { type: TabStopType.LEFT, position: TabStopPosition.MAX / 4 },\n    { type: TabStopType.CENTER, position: TabStopPosition.MAX / 2 },\n    { type: TabStopType.RIGHT, position: TabStopPosition.MAX * 3 / 4 }\n  ],\n  children: [new TextRun(\"Left\\tCenter\\tRight\")]\n})\n```\n\n## Constants & Quick Reference\n- **Underlines:** `SINGLE`, `DOUBLE`, `WAVY`, `DASH`\n- **Borders:** `SINGLE`, `DOUBLE`, `DASHED`, `DOTTED`  \n- **Numbering:** `DECIMAL` (1,2,3), `UPPER_ROMAN` (I,II,III), `LOWER_LETTER` (a,b,c)\n- **Tabs:** `LEFT`, `CENTER`, `RIGHT`, `DECIMAL`\n- **Symbols:** `\"2022\"` (•), `\"00A9\"` (©), `\"00AE\"` (®), `\"2122\"` (™), `\"00B0\"` (°), `\"F070\"` (✓), `\"F0FC\"` (✗)\n\n## Critical Issues & Common Mistakes\n- **CRITICAL: PageBreak must ALWAYS be inside a Paragraph** - standalone PageBreak creates invalid XML that Word cannot open\n- **ALWAYS use ShadingType.CLEAR for table cell shading** - Never use ShadingType.SOLID (causes black background).\n- Measurements in DXA (1440 = 1 inch) | Each table cell needs ≥1 Paragraph | TOC requires HeadingLevel styles only\n- **ALWAYS use custom styles** with Arial font for professional appearance and proper visual hierarchy\n- **ALWAYS set a default font** using `styles.default.document.run.font` - Arial recommended\n- **ALWAYS use columnWidths array for tables** + individual cell widths for compatibility\n- **NEVER use unicode symbols for bullets** - always use proper numbering configuration with `LevelFormat.BULLET` constant (NOT the string \"bullet\")\n- **NEVER use \\n for line breaks anywhere** - always use separate Paragraph elements for each line\n- **ALWAYS use TextRun objects within Paragraph children** - never use text property directly on Paragraph\n- **CRITICAL for images**: ImageRun REQUIRES `type` parameter - always specify \"png\", \"jpg\", \"jpeg\", \"gif\", \"bmp\", or \"svg\"\n- **CRITICAL for bullets**: Must use `LevelFormat.BULLET` constant, not string \"bullet\", and include `text: \"•\"` for the bullet character\n- **CRITICAL for numbering**: Each numbering reference creates an INDEPENDENT list. Same reference = continues numbering (1,2,3 then 4,5,6). Different reference = restarts at 1 (1,2,3 then 1,2,3). Use unique reference names for each separate numbered section!\n- **CRITICAL for TOC**: When using TableOfContents, headings must use HeadingLevel ONLY - do NOT add custom styles to heading paragraphs or TOC will break\n- **Tables**: Set `columnWidths` array + individual cell widths, apply borders to cells not table\n- **Set table margins at TABLE level** for consistent cell padding (avoids repetition per cell)"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  xmlns:cdr=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n    schemaLocation=\"dml-chartDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Double\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedInt\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumData\">\n    <xsd:sequence>\n      <xsd:element name=\"formatCode\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_NumVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numCache\" type=\"CT_NumData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strCache\" type=\"CT_StrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"rich\" type=\"a:CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLanguageID\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"multiLvlStrCache\" type=\"CT_MultiLvlStrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AxDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"multiLvlStrRef\" type=\"CT_MultiLvlStrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strLit\" type=\"CT_StrData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerTx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutTarget\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inner\"/>\n      <xsd:enumeration value=\"outer\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutTarget\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutTarget\" default=\"outer\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"edge\"/>\n      <xsd:enumeration value=\"factor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutMode\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutMode\" default=\"factor\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualLayout\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutTarget\" type=\"CT_LayoutTarget\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"x\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"w\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"h\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Layout\">\n    <xsd:sequence>\n      <xsd:element name=\"manualLayout\" type=\"CT_ManualLayout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Title\">\n    <xsd:sequence>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotX\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-90\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotX\">\n    <xsd:attribute name=\"val\" type=\"ST_RotX\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HPercent\">\n    <xsd:union memberTypes=\"ST_HPercentWithSymbol ST_HPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_HPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotY\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotY\">\n    <xsd:attribute name=\"val\" type=\"ST_RotY\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DepthPercent\">\n    <xsd:union memberTypes=\"ST_DepthPercentWithSymbol ST_DepthPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"20\"/>\n      <xsd:maxInclusive value=\"2000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DepthPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_DepthPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Perspective\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"240\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perspective\">\n    <xsd:attribute name=\"val\" type=\"ST_Perspective\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_View3D\">\n    <xsd:sequence>\n      <xsd:element name=\"rotX\" type=\"CT_RotX\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hPercent\" type=\"CT_HPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rotY\" type=\"CT_RotY\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"depthPercent\" type=\"CT_DepthPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rAngAx\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"perspective\" type=\"CT_Perspective\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface\">\n    <xsd:sequence>\n      <xsd:element name=\"thickness\" type=\"CT_Thickness\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Thickness\">\n    <xsd:union memberTypes=\"ST_ThicknessPercent xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ThicknessPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"([0-9]+)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Thickness\">\n    <xsd:attribute name=\"val\" type=\"ST_Thickness\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DTable\">\n    <xsd:sequence>\n      <xsd:element name=\"showHorzBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVertBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showOutline\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showKeys\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GapAmount\">\n    <xsd:union memberTypes=\"ST_GapAmountPercent ST_GapAmountUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GapAmount\">\n    <xsd:attribute name=\"val\" type=\"ST_GapAmount\" default=\"150%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Overlap\">\n    <xsd:union memberTypes=\"ST_OverlapPercent ST_OverlapByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"(-?0*(([0-9])|([1-9][0-9])|100))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapByte\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-100\"/>\n      <xsd:maxInclusive value=\"100\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Overlap\">\n    <xsd:attribute name=\"val\" type=\"ST_Overlap\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BubbleScale\">\n    <xsd:union memberTypes=\"ST_BubbleScalePercent ST_BubbleScaleUInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-2][0-9][0-9])|300)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScaleUInt\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"300\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BubbleScale\">\n    <xsd:attribute name=\"val\" type=\"ST_BubbleScale\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SizeRepresents\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"w\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SizeRepresents\">\n    <xsd:attribute name=\"val\" type=\"ST_SizeRepresents\" default=\"area\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FirstSliceAng\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FirstSliceAng\">\n    <xsd:attribute name=\"val\" type=\"ST_FirstSliceAng\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HoleSize\">\n    <xsd:union memberTypes=\"ST_HoleSizePercent ST_HoleSizeUByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*([1-9]|([1-8][0-9])|90)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizeUByte\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HoleSize\">\n    <xsd:attribute name=\"val\" type=\"ST_HoleSize\" default=\"10%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SplitType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"val\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SplitType\">\n    <xsd:attribute name=\"val\" type=\"ST_SplitType\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustSplit\">\n    <xsd:sequence>\n      <xsd:element name=\"secondPiePt\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SecondPieSize\">\n    <xsd:union memberTypes=\"ST_SecondPieSizePercent ST_SecondPieSizeUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|(1[0-9][0-9])|200)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizeUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SecondPieSize\">\n    <xsd:attribute name=\"val\" type=\"ST_SecondPieSize\" default=\"75%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceLinked\" type=\"xsd:boolean\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblAlgn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblAlgn\">\n    <xsd:attribute name=\"val\" type=\"ST_LblAlgn\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"inBase\"/>\n      <xsd:enumeration value=\"inEnd\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"outEnd\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_DLblPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_DLblShared\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLblPos\" type=\"CT_DLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLegendKey\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVal\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showCatName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showSerName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPercent\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showBubbleSize\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"separator\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"Group_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbl\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"Group_DLbls\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLeaderLines\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"leaderLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbls\">\n    <xsd:sequence>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbls\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"picture\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"star\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerStyle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerSize\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"72\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerSize\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerSize\" default=\"5\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"symbol\" type=\"CT_MarkerStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"size\" type=\"CT_MarkerSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TrendlineType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"exp\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"log\"/>\n      <xsd:enumeration value=\"movingAvg\"/>\n      <xsd:enumeration value=\"poly\"/>\n      <xsd:enumeration value=\"power\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TrendlineType\">\n    <xsd:attribute name=\"val\" type=\"ST_TrendlineType\" default=\"linear\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Order\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"6\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Order\">\n    <xsd:attribute name=\"val\" type=\"ST_Order\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Period\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Period\">\n    <xsd:attribute name=\"val\" type=\"ST_Period\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrendlineLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Trendline\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineType\" type=\"CT_TrendlineType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_Order\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"period\" type=\"CT_Period\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"intercept\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispRSqr\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispEq\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineLbl\" type=\"CT_TrendlineLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrDir\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrDir\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrBarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"minus\"/>\n      <xsd:enumeration value=\"plus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrBarType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrBarType\" default=\"both\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrValType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"fixedVal\"/>\n      <xsd:enumeration value=\"percentage\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdErr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrValType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrValType\" default=\"fixedVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ErrBars\">\n    <xsd:sequence>\n      <xsd:element name=\"errDir\" type=\"CT_ErrDir\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errBarType\" type=\"CT_ErrBarType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errValType\" type=\"CT_ErrValType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noEndCap\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBar\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBars\">\n    <xsd:sequence>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"downBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SerShared\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_SerTx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AreaSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PieSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleSize\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SurfaceSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Grouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Grouping\">\n    <xsd:attribute name=\"val\" type=\"ST_Grouping\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartLines\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StockChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"3\" maxOccurs=\"4\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ScatterStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineMarker\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"smooth\"/>\n      <xsd:enumeration value=\"smoothMarker\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ScatterStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_ScatterStyle\" default=\"marker\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterChart\">\n    <xsd:sequence>\n      <xsd:element name=\"scatterStyle\" type=\"CT_ScatterStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_ScatterSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RadarStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"filled\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RadarStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_RadarStyle\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarChart\">\n    <xsd:sequence>\n      <xsd:element name=\"radarStyle\" type=\"CT_RadarStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_RadarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"clustered\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarGrouping\">\n    <xsd:attribute name=\"val\" type=\"ST_BarGrouping\" default=\"clustered\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarDir\">\n    <xsd:attribute name=\"val\" type=\"ST_BarDir\" default=\"col\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shape\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cone\"/>\n      <xsd:enumeration value=\"coneToMax\"/>\n      <xsd:enumeration value=\"box\"/>\n      <xsd:enumeration value=\"cylinder\"/>\n      <xsd:enumeration value=\"pyramid\"/>\n      <xsd:enumeration value=\"pyramidToMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:attribute name=\"val\" type=\"ST_Shape\" default=\"box\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_BarChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"barDir\" type=\"CT_BarDir\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grouping\" type=\"CT_BarGrouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_BarChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlap\" type=\"CT_Overlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AreaChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_AreaSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AreaChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Area3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PieChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_PieSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_PieChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pie3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DoughnutChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"holeSize\" type=\"CT_HoleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_OfPieType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"bar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OfPieType\">\n    <xsd:attribute name=\"val\" type=\"ST_OfPieType\" default=\"pie\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfPieChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ofPieType\" type=\"CT_OfPieType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitType\" type=\"CT_SplitType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitPos\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custSplit\" type=\"CT_CustSplit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"secondPieSize\" type=\"CT_SecondPieSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleChart\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BubbleSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleScale\" type=\"CT_BubbleScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showNegBubbles\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sizeRepresents\" type=\"CT_SizeRepresents\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"bandFmt\" type=\"CT_BandFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SurfaceChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"wireframe\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_SurfaceSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"bandFmts\" type=\"CT_BandFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SurfaceChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxPos\">\n    <xsd:attribute name=\"val\" type=\"ST_AxPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Crosses\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"autoZero\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Crosses\">\n    <xsd:attribute name=\"val\" type=\"ST_Crosses\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CrossBetween\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"midCat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CrossBetween\">\n    <xsd:attribute name=\"val\" type=\"ST_CrossBetween\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"out\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickMark\">\n    <xsd:attribute name=\"val\" type=\"ST_TickMark\" default=\"cross\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"high\"/>\n      <xsd:enumeration value=\"low\"/>\n      <xsd:enumeration value=\"nextTo\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_TickLblPos\" default=\"nextTo\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Skip\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Skip\">\n    <xsd:attribute name=\"val\" type=\"ST_Skip\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TimeUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TimeUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_TimeUnit\" default=\"days\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxisUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxisUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_AxisUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BuiltInUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hundreds\"/>\n      <xsd:enumeration value=\"thousands\"/>\n      <xsd:enumeration value=\"tenThousands\"/>\n      <xsd:enumeration value=\"hundredThousands\"/>\n      <xsd:enumeration value=\"millions\"/>\n      <xsd:enumeration value=\"tenMillions\"/>\n      <xsd:enumeration value=\"hundredMillions\"/>\n      <xsd:enumeration value=\"billions\"/>\n      <xsd:enumeration value=\"trillions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BuiltInUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_BuiltInUnit\" default=\"thousands\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stretch\"/>\n      <xsd:enumeration value=\"stack\"/>\n      <xsd:enumeration value=\"stackScale\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureFormat\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureFormat\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureStackUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureStackUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureStackUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureOptions\">\n    <xsd:sequence>\n      <xsd:element name=\"applyToFront\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToSides\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToEnd\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureFormat\" type=\"CT_PictureFormat\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureStackUnit\" type=\"CT_PictureStackUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnitsLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnits\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"custUnit\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"builtInUnit\" type=\"CT_BuiltInUnit\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dispUnitsLbl\" type=\"CT_DispUnitsLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"maxMin\"/>\n      <xsd:enumeration value=\"minMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Orientation\">\n    <xsd:attribute name=\"val\" type=\"ST_Orientation\" default=\"minMax\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LogBase\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LogBase\">\n    <xsd:attribute name=\"val\" type=\"ST_LogBase\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scaling\">\n    <xsd:sequence>\n      <xsd:element name=\"logBase\" type=\"CT_LogBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"orientation\" type=\"CT_Orientation\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"max\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"min\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblOffset\">\n    <xsd:union memberTypes=\"ST_LblOffsetPercent ST_LblOffsetUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblOffset\">\n    <xsd:attribute name=\"val\" type=\"ST_LblOffset\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AxShared\">\n    <xsd:sequence>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scaling\" type=\"CT_Scaling\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axPos\" type=\"CT_AxPos\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblPos\" type=\"CT_TickLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossAx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"crosses\" type=\"CT_Crosses\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"crossesAt\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CatAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblAlgn\" type=\"CT_LblAlgn\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noMultiLvlLbl\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"baseTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ValAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossBetween\" type=\"CT_CrossBetween\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispUnits\" type=\"CT_DispUnits\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PlotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"areaChart\" type=\"CT_AreaChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"area3DChart\" type=\"CT_Area3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lineChart\" type=\"CT_LineChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"line3DChart\" type=\"CT_Line3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"stockChart\" type=\"CT_StockChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"radarChart\" type=\"CT_RadarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"scatterChart\" type=\"CT_ScatterChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pieChart\" type=\"CT_PieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pie3DChart\" type=\"CT_Pie3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"doughnutChart\" type=\"CT_DoughnutChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"barChart\" type=\"CT_BarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bar3DChart\" type=\"CT_Bar3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ofPieChart\" type=\"CT_OfPieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surfaceChart\" type=\"CT_SurfaceChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surface3DChart\" type=\"CT_Surface3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bubbleChart\" type=\"CT_BubbleChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"valAx\" type=\"CT_ValAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"catAx\" type=\"CT_CatAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"dateAx\" type=\"CT_DateAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"serAx\" type=\"CT_SerAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dTable\" type=\"CT_DTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotFmt\" type=\"CT_PivotFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LegendPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LegendPos\">\n    <xsd:attribute name=\"val\" type=\"ST_LegendPos\" default=\"r\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LegendEntryData\">\n    <xsd:sequence>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LegendEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"EG_LegendEntryData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Legend\">\n    <xsd:sequence>\n      <xsd:element name=\"legendPos\" type=\"CT_LegendPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legendEntry\" type=\"CT_LegendEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DispBlanksAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"gap\"/>\n      <xsd:enumeration value=\"zero\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DispBlanksAs\">\n    <xsd:attribute name=\"val\" type=\"ST_DispBlanksAs\" default=\"zero\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chart\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoTitleDeleted\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotFmts\" type=\"CT_PivotFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"view3D\" type=\"CT_View3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"floor\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sideWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotArea\" type=\"CT_PlotArea\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legend\" type=\"CT_Legend\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotVisOnly\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispBlanksAs\" type=\"CT_DispBlanksAs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showDLblsOverMax\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"48\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSource\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Protection\">\n    <xsd:sequence>\n      <xsd:element name=\"chartObject\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"data\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formatting\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userInterface\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"l\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageSetupOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ExternalData\">\n    <xsd:sequence>\n      <xsd:element name=\"autoUpdate\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_PageSetupOrientation\" use=\"optional\"\n      default=\"default\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartSpace\">\n    <xsd:sequence>\n      <xsd:element name=\"date1904\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lang\" type=\"CT_TextLanguageID\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"roundedCorners\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotSource\" type=\"CT_PivotSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_Protection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chart\" type=\"CT_Chart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalData\" type=\"CT_ExternalData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printSettings\" type=\"CT_PrintSettings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userShapes\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"chartSpace\" type=\"CT_ChartSpace\"/>\n  <xsd:element name=\"userShapes\" type=\"cdr:CT_Drawing\"/>\n  <xsd:element name=\"chart\" type=\"CT_RelId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_MarkerCoordinate\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"0.0\"/>\n      <xsd:maxInclusive value=\"1.0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"relSizeAnchor\" type=\"CT_RelSizeAnchor\"/>\n      <xsd:element name=\"absSizeAnchor\" type=\"CT_AbsSizeAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_CTName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_CTCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ClrAppMethod\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HueDir\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"meth\" type=\"ST_ClrAppMethod\" use=\"optional\" default=\"span\"/>\n    <xsd:attribute name=\"hueDir\" type=\"ST_HueDir\" use=\"optional\" default=\"cw\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTStyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"fillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"linClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txLinClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txFillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txEffectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorTransform\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_CTStyleLabel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDef\" type=\"CT_ColorTransform\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdrLst\" type=\"CT_ColorTransformHeaderLst\"/>\n  <xsd:simpleType name=\"ST_PtType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pt\">\n    <xsd:sequence>\n      <xsd:element name=\"prSet\" type=\"CT_ElemPropSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PtType\" use=\"optional\" default=\"node\"/>\n    <xsd:attribute name=\"cxnId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PtList\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_Pt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CxnType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parOf\"/>\n      <xsd:enumeration value=\"presOf\"/>\n      <xsd:enumeration value=\"presParOf\"/>\n      <xsd:enumeration value=\"unknownRelationship\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cxn\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_CxnType\" use=\"optional\" default=\"parOf\"/>\n    <xsd:attribute name=\"srcId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"destId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"srcOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"destOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"parTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sibTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"presId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CxnList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_Cxn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataModel\">\n    <xsd:sequence>\n      <xsd:element name=\"ptLst\" type=\"CT_PtList\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_CxnList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"dataModel\" type=\"CT_DataModel\"/>\n  <xsd:attributeGroup name=\"AG_IteratorAttributes\">\n    <xsd:attribute name=\"axis\" type=\"ST_AxisTypes\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementTypes\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"hideLastTrans\" type=\"ST_Booleans\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"st\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cnt\" type=\"ST_UnsignedInts\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"step\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintAttributes\">\n    <xsd:attribute name=\"type\" type=\"ST_ConstraintType\" use=\"required\"/>\n    <xsd:attribute name=\"for\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"forName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintRefAttributes\">\n    <xsd:attribute name=\"refType\" type=\"ST_ConstraintType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"refFor\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"refForName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"refPtType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_Constraint\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ConstraintRefAttributes\"/>\n    <xsd:attribute name=\"op\" type=\"ST_BoolOperator\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Constraints\">\n    <xsd:sequence>\n      <xsd:element name=\"constr\" type=\"CT_Constraint\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumericRule\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"rule\" type=\"CT_NumericRule\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationOf\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutShapeType\" final=\"restriction\">\n    <xsd:union memberTypes=\"a:ST_ShapeType ST_OutputShapeType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index1\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Adj\">\n    <xsd:attribute name=\"idx\" type=\"ST_Index1\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjLst\">\n    <xsd:sequence>\n      <xsd:element name=\"adj\" type=\"CT_Adj\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"adjLst\" type=\"CT_AdjLst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"type\" type=\"ST_LayoutShapeType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute ref=\"r:blip\" use=\"optional\"/>\n    <xsd:attribute name=\"zOrderOff\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hideGeom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lkTxEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"blipPhldr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"type\" type=\"ST_ParameterId\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ParameterVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Algorithm\">\n    <xsd:sequence>\n      <xsd:element name=\"param\" type=\"CT_Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_AlgorithmType\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutNode\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varLst\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"styleLbl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"chOrder\" type=\"ST_ChildOrderType\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"moveWith\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ForEach\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ref\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_When\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n    <xsd:attribute name=\"func\" type=\"ST_FunctionType\" use=\"required\"/>\n    <xsd:attribute name=\"arg\" type=\"ST_FunctionArgument\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"op\" type=\"ST_FunctionOperator\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FunctionValue\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Otherwise\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Choose\">\n    <xsd:sequence>\n      <xsd:element name=\"if\" type=\"CT_When\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"else\" type=\"CT_Otherwise\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SampleData\">\n    <xsd:sequence>\n      <xsd:element name=\"dataModel\" type=\"CT_DataModel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useDef\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Category\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Categories\">\n    <xsd:sequence>\n      <xsd:element name=\"cat\" type=\"CT_Category\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Name\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Description\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DiagramDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"sampData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"clrData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDef\" type=\"CT_DiagramDefinition\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdrLst\" type=\"CT_DiagramDefinitionHeaderLst\"/>\n  <xsd:complexType name=\"CT_RelIds\">\n    <xsd:attribute ref=\"r:dm\" use=\"required\"/>\n    <xsd:attribute ref=\"r:lo\" use=\"required\"/>\n    <xsd:attribute ref=\"r:qs\" use=\"required\"/>\n    <xsd:attribute ref=\"r:cs\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"relIds\" type=\"CT_RelIds\"/>\n  <xsd:simpleType name=\"ST_ParameterVal\">\n    <xsd:union\n      memberTypes=\"ST_DiagramHorizontalAlignment ST_VerticalAlignment ST_ChildDirection ST_ChildAlignment ST_SecondaryChildAlignment ST_LinearDirection ST_SecondaryLinearDirection ST_StartingElement ST_BendPoint ST_ConnectorRouting ST_ArrowheadStyle ST_ConnectorDimension ST_RotationPath ST_CenterShapeMapping ST_NodeHorizontalAlignment ST_NodeVerticalAlignment ST_FallbackDimension ST_TextDirection ST_PyramidAccentPosition ST_PyramidAccentTextMargin ST_TextBlockDirection ST_TextAnchorHorizontal ST_TextAnchorVertical ST_DiagramTextAlignment ST_AutoTextRotation ST_GrowDirection ST_FlowDirection ST_ContinueDirection ST_Breakpoint ST_Offset ST_HierarchyAlignment xsd:int xsd:double xsd:boolean xsd:string ST_ConnectorPoint\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ModelId\">\n    <xsd:union memberTypes=\"xsd:int s:ST_Guid\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrSetCustVal\">\n    <xsd:union memberTypes=\"s:ST_Percentage xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ElemPropSet\">\n    <xsd:sequence>\n      <xsd:element name=\"presLayoutVars\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"presAssocID\" type=\"ST_ModelId\" use=\"optional\"/>\n    <xsd:attribute name=\"presName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleLbl\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleIdx\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleCnt\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"loTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"loCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coherent3DOff\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"phldrT\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"phldr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custAng\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipVert\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipHor\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzX\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzY\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custT\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleRad\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleInc\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"rev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierBranchStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"hang\"/>\n      <xsd:enumeration value=\"std\"/>\n      <xsd:enumeration value=\"init\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimOneStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"branch\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimLvlStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"lvl\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OrgChart\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NodeCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChildMax\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChildPref\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BulletEnabled\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Direction\">\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" default=\"norm\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierBranchStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_HierBranchStyle\" default=\"std\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimOne\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimOneStr\" default=\"one\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimLvl\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimLvlStr\" default=\"none\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ResizeHandlesStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"rel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ResizeHandles\">\n    <xsd:attribute name=\"val\" type=\"ST_ResizeHandlesStr\" default=\"rel\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutVariablePropertySet\">\n    <xsd:sequence>\n      <xsd:element name=\"orgChart\" type=\"CT_OrgChart\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chMax\" type=\"CT_ChildMax\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chPref\" type=\"CT_ChildPref\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bulletEnabled\" type=\"CT_BulletEnabled\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dir\" type=\"CT_Direction\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hierBranch\" type=\"CT_HierBranchStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animOne\" type=\"CT_AnimOne\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animLvl\" type=\"CT_AnimLvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"resizeHandles\" type=\"CT_ResizeHandles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_SDCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextProps\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"a:CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"CT_TextProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_StyleLabel\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDef\" type=\"CT_StyleDefinition\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdrLst\" type=\"CT_StyleDefinitionHeaderLst\"/>\n  <xsd:simpleType name=\"ST_AlgorithmType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"composite\"/>\n      <xsd:enumeration value=\"conn\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"hierChild\"/>\n      <xsd:enumeration value=\"hierRoot\"/>\n      <xsd:enumeration value=\"pyra\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"snake\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n      <xsd:enumeration value=\"desOrSelf\"/>\n      <xsd:enumeration value=\"par\"/>\n      <xsd:enumeration value=\"ancst\"/>\n      <xsd:enumeration value=\"ancstOrSelf\"/>\n      <xsd:enumeration value=\"followSib\"/>\n      <xsd:enumeration value=\"precedSib\"/>\n      <xsd:enumeration value=\"follow\"/>\n      <xsd:enumeration value=\"preced\"/>\n      <xsd:enumeration value=\"root\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisTypes\">\n    <xsd:list itemType=\"ST_AxisType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BoolOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildOrderType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alignOff\"/>\n      <xsd:enumeration value=\"begMarg\"/>\n      <xsd:enumeration value=\"bendDist\"/>\n      <xsd:enumeration value=\"begPad\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"bMarg\"/>\n      <xsd:enumeration value=\"bOff\"/>\n      <xsd:enumeration value=\"ctrX\"/>\n      <xsd:enumeration value=\"ctrXOff\"/>\n      <xsd:enumeration value=\"ctrY\"/>\n      <xsd:enumeration value=\"ctrYOff\"/>\n      <xsd:enumeration value=\"connDist\"/>\n      <xsd:enumeration value=\"diam\"/>\n      <xsd:enumeration value=\"endMarg\"/>\n      <xsd:enumeration value=\"endPad\"/>\n      <xsd:enumeration value=\"h\"/>\n      <xsd:enumeration value=\"hArH\"/>\n      <xsd:enumeration value=\"hOff\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"lMarg\"/>\n      <xsd:enumeration value=\"lOff\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"rMarg\"/>\n      <xsd:enumeration value=\"rOff\"/>\n      <xsd:enumeration value=\"primFontSz\"/>\n      <xsd:enumeration value=\"pyraAcctRatio\"/>\n      <xsd:enumeration value=\"secFontSz\"/>\n      <xsd:enumeration value=\"sibSp\"/>\n      <xsd:enumeration value=\"secSibSp\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"stemThick\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tMarg\"/>\n      <xsd:enumeration value=\"tOff\"/>\n      <xsd:enumeration value=\"userA\"/>\n      <xsd:enumeration value=\"userB\"/>\n      <xsd:enumeration value=\"userC\"/>\n      <xsd:enumeration value=\"userD\"/>\n      <xsd:enumeration value=\"userE\"/>\n      <xsd:enumeration value=\"userF\"/>\n      <xsd:enumeration value=\"userG\"/>\n      <xsd:enumeration value=\"userH\"/>\n      <xsd:enumeration value=\"userI\"/>\n      <xsd:enumeration value=\"userJ\"/>\n      <xsd:enumeration value=\"userK\"/>\n      <xsd:enumeration value=\"userL\"/>\n      <xsd:enumeration value=\"userM\"/>\n      <xsd:enumeration value=\"userN\"/>\n      <xsd:enumeration value=\"userO\"/>\n      <xsd:enumeration value=\"userP\"/>\n      <xsd:enumeration value=\"userQ\"/>\n      <xsd:enumeration value=\"userR\"/>\n      <xsd:enumeration value=\"userS\"/>\n      <xsd:enumeration value=\"userT\"/>\n      <xsd:enumeration value=\"userU\"/>\n      <xsd:enumeration value=\"userV\"/>\n      <xsd:enumeration value=\"userW\"/>\n      <xsd:enumeration value=\"userX\"/>\n      <xsd:enumeration value=\"userY\"/>\n      <xsd:enumeration value=\"userZ\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"wArH\"/>\n      <xsd:enumeration value=\"wOff\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintRelationship\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"nonNorm\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"nonAsst\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementTypes\">\n    <xsd:list itemType=\"ST_ElementType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ParameterId\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horzAlign\"/>\n      <xsd:enumeration value=\"vertAlign\"/>\n      <xsd:enumeration value=\"chDir\"/>\n      <xsd:enumeration value=\"chAlign\"/>\n      <xsd:enumeration value=\"secChAlign\"/>\n      <xsd:enumeration value=\"linDir\"/>\n      <xsd:enumeration value=\"secLinDir\"/>\n      <xsd:enumeration value=\"stElem\"/>\n      <xsd:enumeration value=\"bendPt\"/>\n      <xsd:enumeration value=\"connRout\"/>\n      <xsd:enumeration value=\"begSty\"/>\n      <xsd:enumeration value=\"endSty\"/>\n      <xsd:enumeration value=\"dim\"/>\n      <xsd:enumeration value=\"rotPath\"/>\n      <xsd:enumeration value=\"ctrShpMap\"/>\n      <xsd:enumeration value=\"nodeHorzAlign\"/>\n      <xsd:enumeration value=\"nodeVertAlign\"/>\n      <xsd:enumeration value=\"fallback\"/>\n      <xsd:enumeration value=\"txDir\"/>\n      <xsd:enumeration value=\"pyraAcctPos\"/>\n      <xsd:enumeration value=\"pyraAcctTxMar\"/>\n      <xsd:enumeration value=\"txBlDir\"/>\n      <xsd:enumeration value=\"txAnchorHorz\"/>\n      <xsd:enumeration value=\"txAnchorVert\"/>\n      <xsd:enumeration value=\"txAnchorHorzCh\"/>\n      <xsd:enumeration value=\"txAnchorVertCh\"/>\n      <xsd:enumeration value=\"parTxLTRAlign\"/>\n      <xsd:enumeration value=\"parTxRTLAlign\"/>\n      <xsd:enumeration value=\"shpTxLTRAlignCh\"/>\n      <xsd:enumeration value=\"shpTxRTLAlignCh\"/>\n      <xsd:enumeration value=\"autoTxRot\"/>\n      <xsd:enumeration value=\"grDir\"/>\n      <xsd:enumeration value=\"flowDir\"/>\n      <xsd:enumeration value=\"contDir\"/>\n      <xsd:enumeration value=\"bkpt\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"hierAlign\"/>\n      <xsd:enumeration value=\"bkPtFixedVal\"/>\n      <xsd:enumeration value=\"stBulletLvl\"/>\n      <xsd:enumeration value=\"stAng\"/>\n      <xsd:enumeration value=\"spanAng\"/>\n      <xsd:enumeration value=\"ar\"/>\n      <xsd:enumeration value=\"lnSpPar\"/>\n      <xsd:enumeration value=\"lnSpAfParP\"/>\n      <xsd:enumeration value=\"lnSpCh\"/>\n      <xsd:enumeration value=\"lnSpAfChP\"/>\n      <xsd:enumeration value=\"rtShortDist\"/>\n      <xsd:enumeration value=\"alignTx\"/>\n      <xsd:enumeration value=\"pyraLvlNode\"/>\n      <xsd:enumeration value=\"pyraAcctBkgdNode\"/>\n      <xsd:enumeration value=\"pyraAcctTxNode\"/>\n      <xsd:enumeration value=\"srcNode\"/>\n      <xsd:enumeration value=\"dstNode\"/>\n      <xsd:enumeration value=\"begPts\"/>\n      <xsd:enumeration value=\"endPts\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ints\">\n    <xsd:list itemType=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedInts\">\n    <xsd:list itemType=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Booleans\">\n    <xsd:list itemType=\"xsd:boolean\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cnt\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"revPos\"/>\n      <xsd:enumeration value=\"posEven\"/>\n      <xsd:enumeration value=\"posOdd\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"depth\"/>\n      <xsd:enumeration value=\"maxDepth\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"neq\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryLinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StartingElement\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"trans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RotationPath\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alongPath\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CenterShapeMapping\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fNode\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BendPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"beg\"/>\n      <xsd:enumeration value=\"def\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorRouting\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"stra\"/>\n      <xsd:enumeration value=\"bend\"/>\n      <xsd:enumeration value=\"curve\"/>\n      <xsd:enumeration value=\"longCurve\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrowheadStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"arr\"/>\n      <xsd:enumeration value=\"noArr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"bCtr\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"midL\"/>\n      <xsd:enumeration value=\"midR\"/>\n      <xsd:enumeration value=\"tCtr\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"radial\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeVerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FallbackDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentPosition\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bef\"/>\n      <xsd:enumeration value=\"aft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentTextMargin\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"step\"/>\n      <xsd:enumeration value=\"stack\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBlockDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorHorizontal\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorVertical\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramTextAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AutoTextRotation\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"upr\"/>\n      <xsd:enumeration value=\"grav\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GrowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FlowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContinueDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"revDir\"/>\n      <xsd:enumeration value=\"sameDir\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Breakpoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"endCnv\"/>\n      <xsd:enumeration value=\"bal\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Offset\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierarchyAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"tCtrCh\"/>\n      <xsd:enumeration value=\"tCtrDes\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"bCtrCh\"/>\n      <xsd:enumeration value=\"bCtrDes\"/>\n      <xsd:enumeration value=\"lT\"/>\n      <xsd:enumeration value=\"lB\"/>\n      <xsd:enumeration value=\"lCtrCh\"/>\n      <xsd:enumeration value=\"lCtrDes\"/>\n      <xsd:enumeration value=\"rT\"/>\n      <xsd:enumeration value=\"rB\"/>\n      <xsd:enumeration value=\"rCtrCh\"/>\n      <xsd:enumeration value=\"rCtrDes\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionValue\" final=\"restriction\">\n    <xsd:union\n      memberTypes=\"xsd:int xsd:boolean ST_Direction ST_HierBranchStyle ST_AnimOneStr ST_AnimLvlStr ST_ResizeHandlesStr\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VariableType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"orgChart\"/>\n      <xsd:enumeration value=\"chMax\"/>\n      <xsd:enumeration value=\"chPref\"/>\n      <xsd:enumeration value=\"bulEnabled\"/>\n      <xsd:enumeration value=\"dir\"/>\n      <xsd:enumeration value=\"hierBranch\"/>\n      <xsd:enumeration value=\"animOne\"/>\n      <xsd:enumeration value=\"animLvl\"/>\n      <xsd:enumeration value=\"resizeHandles\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionArgument\" final=\"restriction\">\n    <xsd:union memberTypes=\"ST_VariableType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OutputShapeType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"conn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:element name=\"lockedCanvas\" type=\"a:CT_GvmlGroupShape\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n    schemaLocation=\"dml-diagram.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n    schemaLocation=\"dml-chart.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n    schemaLocation=\"dml-lockedCanvas.xsd\"/>\n  <xsd:complexType name=\"CT_AudioFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VideoFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QuickTimeFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCDTime\">\n    <xsd:attribute name=\"track\" type=\"xsd:unsignedByte\" use=\"required\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCD\">\n    <xsd:sequence>\n      <xsd:element name=\"st\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Media\">\n    <xsd:choice>\n      <xsd:element name=\"audioCd\" type=\"CT_AudioCD\"/>\n      <xsd:element name=\"wavAudioFile\" type=\"CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"audioFile\" type=\"CT_AudioFile\"/>\n      <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n      <xsd:element name=\"quickTimeFile\" type=\"CT_QuickTimeFile\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n  <xsd:simpleType name=\"ST_StyleMatrixColumnIndex\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontCollectionIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"dk1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dk2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent3\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent4\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent5\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent6\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"folHlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SupplementalFont\">\n    <xsd:attribute name=\"script\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColorList\">\n    <xsd:sequence>\n      <xsd:element name=\"custClr\" type=\"CT_CustomColor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontCollection\">\n    <xsd:sequence>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"font\" type=\"CT_SupplementalFont\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleItem\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"majorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LineStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"effectStyle\" type=\"CT_EffectStyleItem\" minOccurs=\"3\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrix\">\n    <xsd:sequence>\n      <xsd:element name=\"fillStyleLst\" type=\"CT_FillStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnStyleLst\" type=\"CT_LineStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectStyleLst\" type=\"CT_EffectStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgFillStyleLst\" type=\"CT_BackgroundFillStyleList\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeArtExtension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Coordinate\">\n    <xsd:union memberTypes=\"ST_CoordinateUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CoordinateUnqualified\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"-27273042329600\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32\">\n    <xsd:union memberTypes=\"ST_Coordinate32Unqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32Unqualified\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate32\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Angle\">\n    <xsd:attribute name=\"val\" type=\"ST_Angle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minExclusive value=\"-5400000\"/>\n      <xsd:maxExclusive value=\"5400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxExclusive value=\"21600000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedAngle\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:union memberTypes=\"ST_PercentageDecimal s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PercentageDecimal\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Percentage\">\n    <xsd:attribute name=\"val\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:union memberTypes=\"ST_PositivePercentageDecimal s:ST_PositivePercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositivePercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:union memberTypes=\"ST_FixedPercentageDecimal s:ST_FixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"-100000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:union memberTypes=\"ST_PositiveFixedPercentageDecimal s:ST_PositiveFixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ratio\">\n    <xsd:attribute name=\"n\" type=\"xsd:long\" use=\"required\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:long\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point2D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PositiveSize2D\">\n    <xsd:attribute name=\"cx\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ComplementTransform\"/>\n  <xsd:complexType name=\"CT_InverseTransform\"/>\n  <xsd:complexType name=\"CT_GrayscaleTransform\"/>\n  <xsd:complexType name=\"CT_GammaTransform\"/>\n  <xsd:complexType name=\"CT_InverseGammaTransform\"/>\n  <xsd:group name=\"EG_ColorTransform\">\n    <xsd:choice>\n      <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"comp\" type=\"CT_ComplementTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"inv\" type=\"CT_InverseTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gray\" type=\"CT_GrayscaleTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOff\" type=\"CT_FixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hue\" type=\"CT_PositiveFixedAngle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueOff\" type=\"CT_Angle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sat\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"red\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"green\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blue\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gamma\" type=\"CT_GammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invGamma\" type=\"CT_InverseGammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ScRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HslColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SystemColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"scrollBar\"/>\n      <xsd:enumeration value=\"background\"/>\n      <xsd:enumeration value=\"activeCaption\"/>\n      <xsd:enumeration value=\"inactiveCaption\"/>\n      <xsd:enumeration value=\"menu\"/>\n      <xsd:enumeration value=\"window\"/>\n      <xsd:enumeration value=\"windowFrame\"/>\n      <xsd:enumeration value=\"menuText\"/>\n      <xsd:enumeration value=\"windowText\"/>\n      <xsd:enumeration value=\"captionText\"/>\n      <xsd:enumeration value=\"activeBorder\"/>\n      <xsd:enumeration value=\"inactiveBorder\"/>\n      <xsd:enumeration value=\"appWorkspace\"/>\n      <xsd:enumeration value=\"highlight\"/>\n      <xsd:enumeration value=\"highlightText\"/>\n      <xsd:enumeration value=\"btnFace\"/>\n      <xsd:enumeration value=\"btnShadow\"/>\n      <xsd:enumeration value=\"grayText\"/>\n      <xsd:enumeration value=\"btnText\"/>\n      <xsd:enumeration value=\"inactiveCaptionText\"/>\n      <xsd:enumeration value=\"btnHighlight\"/>\n      <xsd:enumeration value=\"3dDkShadow\"/>\n      <xsd:enumeration value=\"3dLight\"/>\n      <xsd:enumeration value=\"infoText\"/>\n      <xsd:enumeration value=\"infoBk\"/>\n      <xsd:enumeration value=\"hotLight\"/>\n      <xsd:enumeration value=\"gradientActiveCaption\"/>\n      <xsd:enumeration value=\"gradientInactiveCaption\"/>\n      <xsd:enumeration value=\"menuHighlight\"/>\n      <xsd:enumeration value=\"menuBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SystemColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SystemColorVal\" use=\"required\"/>\n    <xsd:attribute name=\"lastClr\" type=\"s:ST_HexColorRGB\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SchemeColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bg1\"/>\n      <xsd:enumeration value=\"tx1\"/>\n      <xsd:enumeration value=\"bg2\"/>\n      <xsd:enumeration value=\"tx2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n      <xsd:enumeration value=\"phClr\"/>\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SchemeColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"aliceBlue\"/>\n      <xsd:enumeration value=\"antiqueWhite\"/>\n      <xsd:enumeration value=\"aqua\"/>\n      <xsd:enumeration value=\"aquamarine\"/>\n      <xsd:enumeration value=\"azure\"/>\n      <xsd:enumeration value=\"beige\"/>\n      <xsd:enumeration value=\"bisque\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blanchedAlmond\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"blueViolet\"/>\n      <xsd:enumeration value=\"brown\"/>\n      <xsd:enumeration value=\"burlyWood\"/>\n      <xsd:enumeration value=\"cadetBlue\"/>\n      <xsd:enumeration value=\"chartreuse\"/>\n      <xsd:enumeration value=\"chocolate\"/>\n      <xsd:enumeration value=\"coral\"/>\n      <xsd:enumeration value=\"cornflowerBlue\"/>\n      <xsd:enumeration value=\"cornsilk\"/>\n      <xsd:enumeration value=\"crimson\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGoldenrod\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"darkGrey\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkKhaki\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkOliveGreen\"/>\n      <xsd:enumeration value=\"darkOrange\"/>\n      <xsd:enumeration value=\"darkOrchid\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkSalmon\"/>\n      <xsd:enumeration value=\"darkSeaGreen\"/>\n      <xsd:enumeration value=\"darkSlateBlue\"/>\n      <xsd:enumeration value=\"darkSlateGray\"/>\n      <xsd:enumeration value=\"darkSlateGrey\"/>\n      <xsd:enumeration value=\"darkTurquoise\"/>\n      <xsd:enumeration value=\"darkViolet\"/>\n      <xsd:enumeration value=\"dkBlue\"/>\n      <xsd:enumeration value=\"dkCyan\"/>\n      <xsd:enumeration value=\"dkGoldenrod\"/>\n      <xsd:enumeration value=\"dkGray\"/>\n      <xsd:enumeration value=\"dkGrey\"/>\n      <xsd:enumeration value=\"dkGreen\"/>\n      <xsd:enumeration value=\"dkKhaki\"/>\n      <xsd:enumeration value=\"dkMagenta\"/>\n      <xsd:enumeration value=\"dkOliveGreen\"/>\n      <xsd:enumeration value=\"dkOrange\"/>\n      <xsd:enumeration value=\"dkOrchid\"/>\n      <xsd:enumeration value=\"dkRed\"/>\n      <xsd:enumeration value=\"dkSalmon\"/>\n      <xsd:enumeration value=\"dkSeaGreen\"/>\n      <xsd:enumeration value=\"dkSlateBlue\"/>\n      <xsd:enumeration value=\"dkSlateGray\"/>\n      <xsd:enumeration value=\"dkSlateGrey\"/>\n      <xsd:enumeration value=\"dkTurquoise\"/>\n      <xsd:enumeration value=\"dkViolet\"/>\n      <xsd:enumeration value=\"deepPink\"/>\n      <xsd:enumeration value=\"deepSkyBlue\"/>\n      <xsd:enumeration value=\"dimGray\"/>\n      <xsd:enumeration value=\"dimGrey\"/>\n      <xsd:enumeration value=\"dodgerBlue\"/>\n      <xsd:enumeration value=\"firebrick\"/>\n      <xsd:enumeration value=\"floralWhite\"/>\n      <xsd:enumeration value=\"forestGreen\"/>\n      <xsd:enumeration value=\"fuchsia\"/>\n      <xsd:enumeration value=\"gainsboro\"/>\n      <xsd:enumeration value=\"ghostWhite\"/>\n      <xsd:enumeration value=\"gold\"/>\n      <xsd:enumeration value=\"goldenrod\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"grey\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"greenYellow\"/>\n      <xsd:enumeration value=\"honeydew\"/>\n      <xsd:enumeration value=\"hotPink\"/>\n      <xsd:enumeration value=\"indianRed\"/>\n      <xsd:enumeration value=\"indigo\"/>\n      <xsd:enumeration value=\"ivory\"/>\n      <xsd:enumeration value=\"khaki\"/>\n      <xsd:enumeration value=\"lavender\"/>\n      <xsd:enumeration value=\"lavenderBlush\"/>\n      <xsd:enumeration value=\"lawnGreen\"/>\n      <xsd:enumeration value=\"lemonChiffon\"/>\n      <xsd:enumeration value=\"lightBlue\"/>\n      <xsd:enumeration value=\"lightCoral\"/>\n      <xsd:enumeration value=\"lightCyan\"/>\n      <xsd:enumeration value=\"lightGoldenrodYellow\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"lightGrey\"/>\n      <xsd:enumeration value=\"lightGreen\"/>\n      <xsd:enumeration value=\"lightPink\"/>\n      <xsd:enumeration value=\"lightSalmon\"/>\n      <xsd:enumeration value=\"lightSeaGreen\"/>\n      <xsd:enumeration value=\"lightSkyBlue\"/>\n      <xsd:enumeration value=\"lightSlateGray\"/>\n      <xsd:enumeration value=\"lightSlateGrey\"/>\n      <xsd:enumeration value=\"lightSteelBlue\"/>\n      <xsd:enumeration value=\"lightYellow\"/>\n      <xsd:enumeration value=\"ltBlue\"/>\n      <xsd:enumeration value=\"ltCoral\"/>\n      <xsd:enumeration value=\"ltCyan\"/>\n      <xsd:enumeration value=\"ltGoldenrodYellow\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"ltGrey\"/>\n      <xsd:enumeration value=\"ltGreen\"/>\n      <xsd:enumeration value=\"ltPink\"/>\n      <xsd:enumeration value=\"ltSalmon\"/>\n      <xsd:enumeration value=\"ltSeaGreen\"/>\n      <xsd:enumeration value=\"ltSkyBlue\"/>\n      <xsd:enumeration value=\"ltSlateGray\"/>\n      <xsd:enumeration value=\"ltSlateGrey\"/>\n      <xsd:enumeration value=\"ltSteelBlue\"/>\n      <xsd:enumeration value=\"ltYellow\"/>\n      <xsd:enumeration value=\"lime\"/>\n      <xsd:enumeration value=\"limeGreen\"/>\n      <xsd:enumeration value=\"linen\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"maroon\"/>\n      <xsd:enumeration value=\"medAquamarine\"/>\n      <xsd:enumeration value=\"medBlue\"/>\n      <xsd:enumeration value=\"medOrchid\"/>\n      <xsd:enumeration value=\"medPurple\"/>\n      <xsd:enumeration value=\"medSeaGreen\"/>\n      <xsd:enumeration value=\"medSlateBlue\"/>\n      <xsd:enumeration value=\"medSpringGreen\"/>\n      <xsd:enumeration value=\"medTurquoise\"/>\n      <xsd:enumeration value=\"medVioletRed\"/>\n      <xsd:enumeration value=\"mediumAquamarine\"/>\n      <xsd:enumeration value=\"mediumBlue\"/>\n      <xsd:enumeration value=\"mediumOrchid\"/>\n      <xsd:enumeration value=\"mediumPurple\"/>\n      <xsd:enumeration value=\"mediumSeaGreen\"/>\n      <xsd:enumeration value=\"mediumSlateBlue\"/>\n      <xsd:enumeration value=\"mediumSpringGreen\"/>\n      <xsd:enumeration value=\"mediumTurquoise\"/>\n      <xsd:enumeration value=\"mediumVioletRed\"/>\n      <xsd:enumeration value=\"midnightBlue\"/>\n      <xsd:enumeration value=\"mintCream\"/>\n      <xsd:enumeration value=\"mistyRose\"/>\n      <xsd:enumeration value=\"moccasin\"/>\n      <xsd:enumeration value=\"navajoWhite\"/>\n      <xsd:enumeration value=\"navy\"/>\n      <xsd:enumeration value=\"oldLace\"/>\n      <xsd:enumeration value=\"olive\"/>\n      <xsd:enumeration value=\"oliveDrab\"/>\n      <xsd:enumeration value=\"orange\"/>\n      <xsd:enumeration value=\"orangeRed\"/>\n      <xsd:enumeration value=\"orchid\"/>\n      <xsd:enumeration value=\"paleGoldenrod\"/>\n      <xsd:enumeration value=\"paleGreen\"/>\n      <xsd:enumeration value=\"paleTurquoise\"/>\n      <xsd:enumeration value=\"paleVioletRed\"/>\n      <xsd:enumeration value=\"papayaWhip\"/>\n      <xsd:enumeration value=\"peachPuff\"/>\n      <xsd:enumeration value=\"peru\"/>\n      <xsd:enumeration value=\"pink\"/>\n      <xsd:enumeration value=\"plum\"/>\n      <xsd:enumeration value=\"powderBlue\"/>\n      <xsd:enumeration value=\"purple\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"rosyBrown\"/>\n      <xsd:enumeration value=\"royalBlue\"/>\n      <xsd:enumeration value=\"saddleBrown\"/>\n      <xsd:enumeration value=\"salmon\"/>\n      <xsd:enumeration value=\"sandyBrown\"/>\n      <xsd:enumeration value=\"seaGreen\"/>\n      <xsd:enumeration value=\"seaShell\"/>\n      <xsd:enumeration value=\"sienna\"/>\n      <xsd:enumeration value=\"silver\"/>\n      <xsd:enumeration value=\"skyBlue\"/>\n      <xsd:enumeration value=\"slateBlue\"/>\n      <xsd:enumeration value=\"slateGray\"/>\n      <xsd:enumeration value=\"slateGrey\"/>\n      <xsd:enumeration value=\"snow\"/>\n      <xsd:enumeration value=\"springGreen\"/>\n      <xsd:enumeration value=\"steelBlue\"/>\n      <xsd:enumeration value=\"tan\"/>\n      <xsd:enumeration value=\"teal\"/>\n      <xsd:enumeration value=\"thistle\"/>\n      <xsd:enumeration value=\"tomato\"/>\n      <xsd:enumeration value=\"turquoise\"/>\n      <xsd:enumeration value=\"violet\"/>\n      <xsd:enumeration value=\"wheat\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"whiteSmoke\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"yellowGreen\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_PresetColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_OfficeArtExtension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OfficeArtExtensionList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scale2D\">\n    <xsd:sequence>\n      <xsd:element name=\"sx\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sy\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Transform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupTransform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chOff\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chExt\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point3D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vector3D\">\n    <xsd:attribute name=\"dx\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dy\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dz\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SphereCoords\">\n    <xsd:attribute name=\"lat\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"lon\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeRect\">\n    <xsd:attribute name=\"l\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"t\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RectAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:group name=\"EG_ColorChoice\">\n    <xsd:choice>\n      <xsd:element name=\"scrgbClr\" type=\"CT_ScRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hslClr\" type=\"CT_HslColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sysClr\" type=\"CT_SystemColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstClr\" type=\"CT_PresetColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMRU\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlackWhiteMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clr\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"invGray\"/>\n      <xsd:enumeration value=\"grayWhite\"/>\n      <xsd:enumeration value=\"blackGray\"/>\n      <xsd:enumeration value=\"blackWhite\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Blob\">\n    <xsd:attribute ref=\"r:embed\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:link\" use=\"optional\" default=\"\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_EmbeddedWAVAudioFile\">\n    <xsd:attribute ref=\"r:embed\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:sequence>\n      <xsd:element name=\"snd\" type=\"CT_EmbeddedWAVAudioFile\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalidUrl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"action\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tooltip\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"highlightClick\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"endSnd\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DrawingElementId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Locking\">\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noEditPoints\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noAdjustHandles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeArrowheads\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeShapeType\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_ConnectorLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noTextEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noCrop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noUngrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noDrilldown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ContentPartLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkHover\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"descr\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"spLocks\" type=\"CT_ShapeLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"txBox\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualConnectorProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cxnSpLocks\" type=\"CT_ConnectorLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualPictureProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"picLocks\" type=\"CT_PictureLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preferRelativeResize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGroupDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"grpSpLocks\" type=\"CT_GroupLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGraphicFrameProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicFrameLocks\" type=\"CT_GraphicalObjectFrameLocking\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualContentPartProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cpLocks\" type=\"CT_ContentPartLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isComment\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectData\">\n    <xsd:sequence>\n      <xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"strict\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObject\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicData\" type=\"CT_GraphicalObjectData\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"graphic\" type=\"CT_GraphicalObject\"/>\n  <xsd:simpleType name=\"ST_ChartBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"allPts\"/>\n      <xsd:enumeration value=\"gridLegend\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DgmBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"bg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmElement\">\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"optional\"\n      default=\"{00000000-0000-0000-0000-000000000000}\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_DgmBuildStep\" use=\"optional\" default=\"sp\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationChartElement\">\n    <xsd:attribute name=\"seriesIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"categoryIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_ChartBuildStep\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationElementChoice\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"dgm\" type=\"CT_AnimationDgmElement\"/>\n      <xsd:element name=\"chart\" type=\"CT_AnimationChartElement\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"lvlOne\"/>\n      <xsd:enumeration value=\"lvlAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationDgmOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationDgmBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationChartOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationChartBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationChartOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationChartBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationGraphicalObjectBuildProperties\">\n    <xsd:choice>\n      <xsd:element name=\"bldDgm\" type=\"CT_AnimationDgmBuildProperties\"/>\n      <xsd:element name=\"bldChart\" type=\"CT_AnimationChartBuildProperties\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFormatting\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WholeE2oFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlUseShapeRectangle\"/>\n  <xsd:complexType name=\"CT_GvmlTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"useSpRect\" type=\"CT_GvmlUseShapeRectangle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_GvmlShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_GvmlConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"CT_NonVisualPictureProperties\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPicture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_GvmlPictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GvmlGraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element ref=\"graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GvmlGroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\"/>\n        <xsd:element name=\"sp\" type=\"CT_GvmlShape\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_GvmlConnector\"/>\n        <xsd:element name=\"pic\" type=\"CT_GvmlPicture\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GvmlGraphicalObjectFrame\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GvmlGroupShape\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetCameraType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueTop\"/>\n      <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n      <xsd:enumeration value=\"legacyObliqueLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueFront\"/>\n      <xsd:enumeration value=\"legacyObliqueRight\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueBottom\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n      <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n      <xsd:enumeration value=\"orthographicFront\"/>\n      <xsd:enumeration value=\"isometricTopUp\"/>\n      <xsd:enumeration value=\"isometricTopDown\"/>\n      <xsd:enumeration value=\"isometricBottomUp\"/>\n      <xsd:enumeration value=\"isometricBottomDown\"/>\n      <xsd:enumeration value=\"isometricLeftUp\"/>\n      <xsd:enumeration value=\"isometricLeftDown\"/>\n      <xsd:enumeration value=\"isometricRightUp\"/>\n      <xsd:enumeration value=\"isometricRightDown\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n      <xsd:enumeration value=\"obliqueTopLeft\"/>\n      <xsd:enumeration value=\"obliqueTop\"/>\n      <xsd:enumeration value=\"obliqueTopRight\"/>\n      <xsd:enumeration value=\"obliqueLeft\"/>\n      <xsd:enumeration value=\"obliqueRight\"/>\n      <xsd:enumeration value=\"obliqueBottomLeft\"/>\n      <xsd:enumeration value=\"obliqueBottom\"/>\n      <xsd:enumeration value=\"obliqueBottomRight\"/>\n      <xsd:enumeration value=\"perspectiveFront\"/>\n      <xsd:enumeration value=\"perspectiveLeft\"/>\n      <xsd:enumeration value=\"perspectiveRight\"/>\n      <xsd:enumeration value=\"perspectiveAbove\"/>\n      <xsd:enumeration value=\"perspectiveBelow\"/>\n      <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveRelaxed\"/>\n      <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FOVAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"10800000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Camera\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetCameraType\" use=\"required\"/>\n    <xsd:attribute name=\"fov\" type=\"ST_FOVAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"zoom\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LightRigDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LightRigType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyFlat1\"/>\n      <xsd:enumeration value=\"legacyFlat2\"/>\n      <xsd:enumeration value=\"legacyFlat3\"/>\n      <xsd:enumeration value=\"legacyFlat4\"/>\n      <xsd:enumeration value=\"legacyNormal1\"/>\n      <xsd:enumeration value=\"legacyNormal2\"/>\n      <xsd:enumeration value=\"legacyNormal3\"/>\n      <xsd:enumeration value=\"legacyNormal4\"/>\n      <xsd:enumeration value=\"legacyHarsh1\"/>\n      <xsd:enumeration value=\"legacyHarsh2\"/>\n      <xsd:enumeration value=\"legacyHarsh3\"/>\n      <xsd:enumeration value=\"legacyHarsh4\"/>\n      <xsd:enumeration value=\"threePt\"/>\n      <xsd:enumeration value=\"balanced\"/>\n      <xsd:enumeration value=\"soft\"/>\n      <xsd:enumeration value=\"harsh\"/>\n      <xsd:enumeration value=\"flood\"/>\n      <xsd:enumeration value=\"contrasting\"/>\n      <xsd:enumeration value=\"morning\"/>\n      <xsd:enumeration value=\"sunrise\"/>\n      <xsd:enumeration value=\"sunset\"/>\n      <xsd:enumeration value=\"chilly\"/>\n      <xsd:enumeration value=\"freezing\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"twoPt\"/>\n      <xsd:enumeration value=\"glow\"/>\n      <xsd:enumeration value=\"brightRoom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LightRig\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scene3D\">\n    <xsd:sequence>\n      <xsd:element name=\"camera\" type=\"CT_Camera\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backdrop\" type=\"CT_Backdrop\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Backdrop\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_Point3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"norm\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"up\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BevelPresetType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relaxedInset\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"slope\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"softRound\"/>\n      <xsd:enumeration value=\"convex\"/>\n      <xsd:enumeration value=\"coolSlant\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"riblet\"/>\n      <xsd:enumeration value=\"hardEdge\"/>\n      <xsd:enumeration value=\"artDeco\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Bevel\">\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\" default=\"circle\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetMaterialType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyMatte\"/>\n      <xsd:enumeration value=\"legacyPlastic\"/>\n      <xsd:enumeration value=\"legacyMetal\"/>\n      <xsd:enumeration value=\"legacyWireframe\"/>\n      <xsd:enumeration value=\"matte\"/>\n      <xsd:enumeration value=\"plastic\"/>\n      <xsd:enumeration value=\"metal\"/>\n      <xsd:enumeration value=\"warmMatte\"/>\n      <xsd:enumeration value=\"translucentPowder\"/>\n      <xsd:enumeration value=\"powder\"/>\n      <xsd:enumeration value=\"dkEdge\"/>\n      <xsd:enumeration value=\"softEdge\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"softmetal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"extrusionH\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"contourW\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"\n      default=\"warmMatte\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FlatText\">\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Text3D\">\n    <xsd:choice>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"flatTx\" type=\"CT_FlatText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AlphaBiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaCeilingEffect\"/>\n  <xsd:complexType name=\"CT_AlphaFloorEffect\"/>\n  <xsd:complexType name=\"CT_AlphaInverseEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateFixedEffect\">\n    <xsd:attribute name=\"amt\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaOutsetEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaReplaceEffect\">\n    <xsd:attribute name=\"a\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlurEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"grow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorChangeEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"clrFrom\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrTo\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useA\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorReplaceEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DuotoneEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GrayscaleEffect\"/>\n  <xsd:complexType name=\"CT_HSLEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InnerShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LuminanceEffect\">\n    <xsd:attribute name=\"bright\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"contrast\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OuterShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetShadowVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shdw1\"/>\n      <xsd:enumeration value=\"shdw2\"/>\n      <xsd:enumeration value=\"shdw3\"/>\n      <xsd:enumeration value=\"shdw4\"/>\n      <xsd:enumeration value=\"shdw5\"/>\n      <xsd:enumeration value=\"shdw6\"/>\n      <xsd:enumeration value=\"shdw7\"/>\n      <xsd:enumeration value=\"shdw8\"/>\n      <xsd:enumeration value=\"shdw9\"/>\n      <xsd:enumeration value=\"shdw10\"/>\n      <xsd:enumeration value=\"shdw11\"/>\n      <xsd:enumeration value=\"shdw12\"/>\n      <xsd:enumeration value=\"shdw13\"/>\n      <xsd:enumeration value=\"shdw14\"/>\n      <xsd:enumeration value=\"shdw15\"/>\n      <xsd:enumeration value=\"shdw16\"/>\n      <xsd:enumeration value=\"shdw17\"/>\n      <xsd:enumeration value=\"shdw18\"/>\n      <xsd:enumeration value=\"shdw19\"/>\n      <xsd:enumeration value=\"shdw20\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetShadowVal\" use=\"required\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReflectionEffect\">\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"stA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"stPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fadeDir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"5400000\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeOffsetEffect\">\n    <xsd:attribute name=\"tx\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SoftEdgesEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TintEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"amt\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransformEffect\">\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NoFillProperties\"/>\n  <xsd:complexType name=\"CT_SolidColorFillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinearShadeProperties\">\n    <xsd:attribute name=\"ang\" type=\"ST_PositiveFixedAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"scaled\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PathShadeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shape\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PathShadeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShadeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"path\" type=\"CT_PathShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TileFlipMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n      <xsd:enumeration value=\"xy\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pos\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tileRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TileInfoProperties\">\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StretchInfoProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FillModeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"tile\" type=\"CT_TileInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stretch\" type=\"CT_StretchInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_BlipCompression\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"hqprint\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Blip\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Blob\"/>\n    <xsd:attribute name=\"cstate\" type=\"ST_BlipCompression\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlipFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srcRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillModeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetPatternVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"ltHorz\"/>\n      <xsd:enumeration value=\"ltVert\"/>\n      <xsd:enumeration value=\"dkHorz\"/>\n      <xsd:enumeration value=\"dkVert\"/>\n      <xsd:enumeration value=\"narHorz\"/>\n      <xsd:enumeration value=\"narVert\"/>\n      <xsd:enumeration value=\"dashHorz\"/>\n      <xsd:enumeration value=\"dashVert\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"dnDiag\"/>\n      <xsd:enumeration value=\"upDiag\"/>\n      <xsd:enumeration value=\"ltDnDiag\"/>\n      <xsd:enumeration value=\"ltUpDiag\"/>\n      <xsd:enumeration value=\"dkDnDiag\"/>\n      <xsd:enumeration value=\"dkUpDiag\"/>\n      <xsd:enumeration value=\"wdDnDiag\"/>\n      <xsd:enumeration value=\"wdUpDiag\"/>\n      <xsd:enumeration value=\"dashDnDiag\"/>\n      <xsd:enumeration value=\"dashUpDiag\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"smCheck\"/>\n      <xsd:enumeration value=\"lgCheck\"/>\n      <xsd:enumeration value=\"smGrid\"/>\n      <xsd:enumeration value=\"lgGrid\"/>\n      <xsd:enumeration value=\"dotGrid\"/>\n      <xsd:enumeration value=\"smConfetti\"/>\n      <xsd:enumeration value=\"lgConfetti\"/>\n      <xsd:enumeration value=\"horzBrick\"/>\n      <xsd:enumeration value=\"diagBrick\"/>\n      <xsd:enumeration value=\"solidDmnd\"/>\n      <xsd:enumeration value=\"openDmnd\"/>\n      <xsd:enumeration value=\"dotDmnd\"/>\n      <xsd:enumeration value=\"plaid\"/>\n      <xsd:enumeration value=\"sphere\"/>\n      <xsd:enumeration value=\"weave\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"shingle\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"trellis\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PatternFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetPatternVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupFillProperties\"/>\n  <xsd:group name=\"EG_FillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpFill\" type=\"CT_GroupFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlendMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"over\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"lighten\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FillOverlayEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectReference\">\n    <xsd:attribute name=\"ref\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Effect\">\n    <xsd:choice>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effect\" type=\"CT_EffectReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOutset\" type=\"CT_AlphaOutsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blend\" type=\"CT_BlendEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_FillEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"relOff\" type=\"CT_RelativeOffsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_TransformEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_EffectContainerType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sib\"/>\n      <xsd:enumeration value=\"tree\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EffectContainer\">\n    <xsd:group ref=\"EG_Effect\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"type\" type=\"ST_EffectContainerType\" use=\"optional\" default=\"sib\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlendEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectList\">\n    <xsd:sequence>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_EffectProperties\">\n    <xsd:choice>\n      <xsd:element name=\"effectLst\" type=\"CT_EffectList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectDag\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_EffectProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"blip\" type=\"CT_Blip\"/>\n  <xsd:simpleType name=\"ST_ShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineInv\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"rtTriangle\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"parallelogram\"/>\n      <xsd:enumeration value=\"trapezoid\"/>\n      <xsd:enumeration value=\"nonIsoscelesTrapezoid\"/>\n      <xsd:enumeration value=\"pentagon\"/>\n      <xsd:enumeration value=\"hexagon\"/>\n      <xsd:enumeration value=\"heptagon\"/>\n      <xsd:enumeration value=\"octagon\"/>\n      <xsd:enumeration value=\"decagon\"/>\n      <xsd:enumeration value=\"dodecagon\"/>\n      <xsd:enumeration value=\"star4\"/>\n      <xsd:enumeration value=\"star5\"/>\n      <xsd:enumeration value=\"star6\"/>\n      <xsd:enumeration value=\"star7\"/>\n      <xsd:enumeration value=\"star8\"/>\n      <xsd:enumeration value=\"star10\"/>\n      <xsd:enumeration value=\"star12\"/>\n      <xsd:enumeration value=\"star16\"/>\n      <xsd:enumeration value=\"star24\"/>\n      <xsd:enumeration value=\"star32\"/>\n      <xsd:enumeration value=\"roundRect\"/>\n      <xsd:enumeration value=\"round1Rect\"/>\n      <xsd:enumeration value=\"round2SameRect\"/>\n      <xsd:enumeration value=\"round2DiagRect\"/>\n      <xsd:enumeration value=\"snipRoundRect\"/>\n      <xsd:enumeration value=\"snip1Rect\"/>\n      <xsd:enumeration value=\"snip2SameRect\"/>\n      <xsd:enumeration value=\"snip2DiagRect\"/>\n      <xsd:enumeration value=\"plaque\"/>\n      <xsd:enumeration value=\"ellipse\"/>\n      <xsd:enumeration value=\"teardrop\"/>\n      <xsd:enumeration value=\"homePlate\"/>\n      <xsd:enumeration value=\"chevron\"/>\n      <xsd:enumeration value=\"pieWedge\"/>\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"blockArc\"/>\n      <xsd:enumeration value=\"donut\"/>\n      <xsd:enumeration value=\"noSmoking\"/>\n      <xsd:enumeration value=\"rightArrow\"/>\n      <xsd:enumeration value=\"leftArrow\"/>\n      <xsd:enumeration value=\"upArrow\"/>\n      <xsd:enumeration value=\"downArrow\"/>\n      <xsd:enumeration value=\"stripedRightArrow\"/>\n      <xsd:enumeration value=\"notchedRightArrow\"/>\n      <xsd:enumeration value=\"bentUpArrow\"/>\n      <xsd:enumeration value=\"leftRightArrow\"/>\n      <xsd:enumeration value=\"upDownArrow\"/>\n      <xsd:enumeration value=\"leftUpArrow\"/>\n      <xsd:enumeration value=\"leftRightUpArrow\"/>\n      <xsd:enumeration value=\"quadArrow\"/>\n      <xsd:enumeration value=\"leftArrowCallout\"/>\n      <xsd:enumeration value=\"rightArrowCallout\"/>\n      <xsd:enumeration value=\"upArrowCallout\"/>\n      <xsd:enumeration value=\"downArrowCallout\"/>\n      <xsd:enumeration value=\"leftRightArrowCallout\"/>\n      <xsd:enumeration value=\"upDownArrowCallout\"/>\n      <xsd:enumeration value=\"quadArrowCallout\"/>\n      <xsd:enumeration value=\"bentArrow\"/>\n      <xsd:enumeration value=\"uturnArrow\"/>\n      <xsd:enumeration value=\"circularArrow\"/>\n      <xsd:enumeration value=\"leftCircularArrow\"/>\n      <xsd:enumeration value=\"leftRightCircularArrow\"/>\n      <xsd:enumeration value=\"curvedRightArrow\"/>\n      <xsd:enumeration value=\"curvedLeftArrow\"/>\n      <xsd:enumeration value=\"curvedUpArrow\"/>\n      <xsd:enumeration value=\"curvedDownArrow\"/>\n      <xsd:enumeration value=\"swooshArrow\"/>\n      <xsd:enumeration value=\"cube\"/>\n      <xsd:enumeration value=\"can\"/>\n      <xsd:enumeration value=\"lightningBolt\"/>\n      <xsd:enumeration value=\"heart\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"moon\"/>\n      <xsd:enumeration value=\"smileyFace\"/>\n      <xsd:enumeration value=\"irregularSeal1\"/>\n      <xsd:enumeration value=\"irregularSeal2\"/>\n      <xsd:enumeration value=\"foldedCorner\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"halfFrame\"/>\n      <xsd:enumeration value=\"corner\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"chord\"/>\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"leftBracket\"/>\n      <xsd:enumeration value=\"rightBracket\"/>\n      <xsd:enumeration value=\"leftBrace\"/>\n      <xsd:enumeration value=\"rightBrace\"/>\n      <xsd:enumeration value=\"bracketPair\"/>\n      <xsd:enumeration value=\"bracePair\"/>\n      <xsd:enumeration value=\"straightConnector1\"/>\n      <xsd:enumeration value=\"bentConnector2\"/>\n      <xsd:enumeration value=\"bentConnector3\"/>\n      <xsd:enumeration value=\"bentConnector4\"/>\n      <xsd:enumeration value=\"bentConnector5\"/>\n      <xsd:enumeration value=\"curvedConnector2\"/>\n      <xsd:enumeration value=\"curvedConnector3\"/>\n      <xsd:enumeration value=\"curvedConnector4\"/>\n      <xsd:enumeration value=\"curvedConnector5\"/>\n      <xsd:enumeration value=\"callout1\"/>\n      <xsd:enumeration value=\"callout2\"/>\n      <xsd:enumeration value=\"callout3\"/>\n      <xsd:enumeration value=\"accentCallout1\"/>\n      <xsd:enumeration value=\"accentCallout2\"/>\n      <xsd:enumeration value=\"accentCallout3\"/>\n      <xsd:enumeration value=\"borderCallout1\"/>\n      <xsd:enumeration value=\"borderCallout2\"/>\n      <xsd:enumeration value=\"borderCallout3\"/>\n      <xsd:enumeration value=\"accentBorderCallout1\"/>\n      <xsd:enumeration value=\"accentBorderCallout2\"/>\n      <xsd:enumeration value=\"accentBorderCallout3\"/>\n      <xsd:enumeration value=\"wedgeRectCallout\"/>\n      <xsd:enumeration value=\"wedgeRoundRectCallout\"/>\n      <xsd:enumeration value=\"wedgeEllipseCallout\"/>\n      <xsd:enumeration value=\"cloudCallout\"/>\n      <xsd:enumeration value=\"cloud\"/>\n      <xsd:enumeration value=\"ribbon\"/>\n      <xsd:enumeration value=\"ribbon2\"/>\n      <xsd:enumeration value=\"ellipseRibbon\"/>\n      <xsd:enumeration value=\"ellipseRibbon2\"/>\n      <xsd:enumeration value=\"leftRightRibbon\"/>\n      <xsd:enumeration value=\"verticalScroll\"/>\n      <xsd:enumeration value=\"horizontalScroll\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"flowChartProcess\"/>\n      <xsd:enumeration value=\"flowChartDecision\"/>\n      <xsd:enumeration value=\"flowChartInputOutput\"/>\n      <xsd:enumeration value=\"flowChartPredefinedProcess\"/>\n      <xsd:enumeration value=\"flowChartInternalStorage\"/>\n      <xsd:enumeration value=\"flowChartDocument\"/>\n      <xsd:enumeration value=\"flowChartMultidocument\"/>\n      <xsd:enumeration value=\"flowChartTerminator\"/>\n      <xsd:enumeration value=\"flowChartPreparation\"/>\n      <xsd:enumeration value=\"flowChartManualInput\"/>\n      <xsd:enumeration value=\"flowChartManualOperation\"/>\n      <xsd:enumeration value=\"flowChartConnector\"/>\n      <xsd:enumeration value=\"flowChartPunchedCard\"/>\n      <xsd:enumeration value=\"flowChartPunchedTape\"/>\n      <xsd:enumeration value=\"flowChartSummingJunction\"/>\n      <xsd:enumeration value=\"flowChartOr\"/>\n      <xsd:enumeration value=\"flowChartCollate\"/>\n      <xsd:enumeration value=\"flowChartSort\"/>\n      <xsd:enumeration value=\"flowChartExtract\"/>\n      <xsd:enumeration value=\"flowChartMerge\"/>\n      <xsd:enumeration value=\"flowChartOfflineStorage\"/>\n      <xsd:enumeration value=\"flowChartOnlineStorage\"/>\n      <xsd:enumeration value=\"flowChartMagneticTape\"/>\n      <xsd:enumeration value=\"flowChartMagneticDisk\"/>\n      <xsd:enumeration value=\"flowChartMagneticDrum\"/>\n      <xsd:enumeration value=\"flowChartDisplay\"/>\n      <xsd:enumeration value=\"flowChartDelay\"/>\n      <xsd:enumeration value=\"flowChartAlternateProcess\"/>\n      <xsd:enumeration value=\"flowChartOffpageConnector\"/>\n      <xsd:enumeration value=\"actionButtonBlank\"/>\n      <xsd:enumeration value=\"actionButtonHome\"/>\n      <xsd:enumeration value=\"actionButtonHelp\"/>\n      <xsd:enumeration value=\"actionButtonInformation\"/>\n      <xsd:enumeration value=\"actionButtonForwardNext\"/>\n      <xsd:enumeration value=\"actionButtonBackPrevious\"/>\n      <xsd:enumeration value=\"actionButtonEnd\"/>\n      <xsd:enumeration value=\"actionButtonBeginning\"/>\n      <xsd:enumeration value=\"actionButtonReturn\"/>\n      <xsd:enumeration value=\"actionButtonDocument\"/>\n      <xsd:enumeration value=\"actionButtonSound\"/>\n      <xsd:enumeration value=\"actionButtonMovie\"/>\n      <xsd:enumeration value=\"gear6\"/>\n      <xsd:enumeration value=\"gear9\"/>\n      <xsd:enumeration value=\"funnel\"/>\n      <xsd:enumeration value=\"mathPlus\"/>\n      <xsd:enumeration value=\"mathMinus\"/>\n      <xsd:enumeration value=\"mathMultiply\"/>\n      <xsd:enumeration value=\"mathDivide\"/>\n      <xsd:enumeration value=\"mathEqual\"/>\n      <xsd:enumeration value=\"mathNotEqual\"/>\n      <xsd:enumeration value=\"cornerTabs\"/>\n      <xsd:enumeration value=\"squareTabs\"/>\n      <xsd:enumeration value=\"plaqueTabs\"/>\n      <xsd:enumeration value=\"chartX\"/>\n      <xsd:enumeration value=\"chartStar\"/>\n      <xsd:enumeration value=\"chartPlus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"textNoShape\"/>\n      <xsd:enumeration value=\"textPlain\"/>\n      <xsd:enumeration value=\"textStop\"/>\n      <xsd:enumeration value=\"textTriangle\"/>\n      <xsd:enumeration value=\"textTriangleInverted\"/>\n      <xsd:enumeration value=\"textChevron\"/>\n      <xsd:enumeration value=\"textChevronInverted\"/>\n      <xsd:enumeration value=\"textRingInside\"/>\n      <xsd:enumeration value=\"textRingOutside\"/>\n      <xsd:enumeration value=\"textArchUp\"/>\n      <xsd:enumeration value=\"textArchDown\"/>\n      <xsd:enumeration value=\"textCircle\"/>\n      <xsd:enumeration value=\"textButton\"/>\n      <xsd:enumeration value=\"textArchUpPour\"/>\n      <xsd:enumeration value=\"textArchDownPour\"/>\n      <xsd:enumeration value=\"textCirclePour\"/>\n      <xsd:enumeration value=\"textButtonPour\"/>\n      <xsd:enumeration value=\"textCurveUp\"/>\n      <xsd:enumeration value=\"textCurveDown\"/>\n      <xsd:enumeration value=\"textCanUp\"/>\n      <xsd:enumeration value=\"textCanDown\"/>\n      <xsd:enumeration value=\"textWave1\"/>\n      <xsd:enumeration value=\"textWave2\"/>\n      <xsd:enumeration value=\"textDoubleWave1\"/>\n      <xsd:enumeration value=\"textWave4\"/>\n      <xsd:enumeration value=\"textInflate\"/>\n      <xsd:enumeration value=\"textDeflate\"/>\n      <xsd:enumeration value=\"textInflateBottom\"/>\n      <xsd:enumeration value=\"textDeflateBottom\"/>\n      <xsd:enumeration value=\"textInflateTop\"/>\n      <xsd:enumeration value=\"textDeflateTop\"/>\n      <xsd:enumeration value=\"textDeflateInflate\"/>\n      <xsd:enumeration value=\"textDeflateInflateDeflate\"/>\n      <xsd:enumeration value=\"textFadeRight\"/>\n      <xsd:enumeration value=\"textFadeLeft\"/>\n      <xsd:enumeration value=\"textFadeUp\"/>\n      <xsd:enumeration value=\"textFadeDown\"/>\n      <xsd:enumeration value=\"textSlantUp\"/>\n      <xsd:enumeration value=\"textSlantDown\"/>\n      <xsd:enumeration value=\"textCascadeUp\"/>\n      <xsd:enumeration value=\"textCascadeDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideName\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideFormula\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GeomGuide\">\n    <xsd:attribute name=\"name\" type=\"ST_GeomGuideName\" use=\"required\"/>\n    <xsd:attribute name=\"fmla\" type=\"ST_GeomGuideFormula\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomGuideList\">\n    <xsd:sequence>\n      <xsd:element name=\"gd\" type=\"CT_GeomGuide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AdjCoordinate\">\n    <xsd:union memberTypes=\"ST_Coordinate ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AdjAngle\">\n    <xsd:union memberTypes=\"ST_Angle ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AdjPoint2D\">\n    <xsd:attribute name=\"x\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomRect\">\n    <xsd:attribute name=\"l\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XYAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefX\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefY\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolarAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefR\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefAng\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"maxAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSite\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ang\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjustHandleList\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"ahXY\" type=\"CT_XYAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahPolar\" type=\"CT_PolarAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSiteList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_ConnectionSite\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DMoveTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DLineTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DArcTo\">\n    <xsd:attribute name=\"wR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"hR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"stAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n    <xsd:attribute name=\"swAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DQuadBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DCubicBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"3\" maxOccurs=\"3\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DClose\"/>\n  <xsd:simpleType name=\"ST_PathFillMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"lighten\"/>\n      <xsd:enumeration value=\"lightenLess\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"darkenLess\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Path2D\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"close\" type=\"CT_Path2DClose\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_Path2DMoveTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTo\" type=\"CT_Path2DLineTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"arcTo\" type=\"CT_Path2DArcTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"quadBezTo\" type=\"CT_Path2DQuadBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cubicBezTo\" type=\"CT_Path2DCubicBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_PathFillMode\" use=\"optional\" default=\"norm\"/>\n    <xsd:attribute name=\"stroke\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"extrusionOk\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DList\">\n    <xsd:sequence>\n      <xsd:element name=\"path\" type=\"CT_Path2D\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_ShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_TextShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gdLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahLst\" type=\"CT_AdjustHandleList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_ConnectionSiteList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rect\" type=\"CT_GeomRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pathLst\" type=\"CT_Path2DList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Geometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstGeom\" type=\"CT_PresetGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextGeometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineEndType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"stealth\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"arrow\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndWidth\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndLength\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineEndProperties\">\n    <xsd:attribute name=\"type\" type=\"ST_LineEndType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"w\" type=\"ST_LineEndWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"len\" type=\"ST_LineEndLength\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineFillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineJoinBevel\"/>\n  <xsd:complexType name=\"CT_LineJoinRound\"/>\n  <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n    <xsd:attribute name=\"lim\" type=\"ST_PositivePercentage\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineJoinProperties\">\n    <xsd:choice>\n      <xsd:element name=\"round\" type=\"CT_LineJoinRound\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevel\" type=\"CT_LineJoinBevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PresetLineDashVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"lgDash\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"lgDashDot\"/>\n      <xsd:enumeration value=\"lgDashDotDot\"/>\n      <xsd:enumeration value=\"sysDash\"/>\n      <xsd:enumeration value=\"sysDot\"/>\n      <xsd:enumeration value=\"sysDashDot\"/>\n      <xsd:enumeration value=\"sysDashDotDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetLineDashProperties\">\n    <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStop\">\n    <xsd:attribute name=\"d\" type=\"ST_PositivePercentage\" use=\"required\"/>\n    <xsd:attribute name=\"sp\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"ds\" type=\"CT_DashStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineDashProperties\">\n    <xsd:choice>\n      <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDash\" type=\"CT_DashStopList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineCap\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rnd\"/>\n      <xsd:enumeration value=\"sq\"/>\n      <xsd:enumeration value=\"flat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineWidth\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"20116800\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PenAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CompoundLine\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"tri\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineFillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tailEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_LineWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_LineCap\" use=\"optional\"/>\n    <xsd:attribute name=\"cmpd\" type=\"ST_CompoundLine\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_PenAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShapeID\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Geometry\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_GroupTransform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrixReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_StyleMatrixColumnIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_FontCollectionIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefaultShapeDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectStyleDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"spDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_ColorMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bg1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"hlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"folHlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMappingOverride\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"masterClrMapping\" type=\"CT_EmptyElement\"/>\n        <xsd:element name=\"overrideClrMapping\" type=\"CT_ColorMapping\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeAndMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeList\">\n    <xsd:sequence>\n      <xsd:element name=\"extraClrScheme\" type=\"CT_ColorSchemeAndMapping\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"objectDefaults\" type=\"CT_ObjectStyleDefaults\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extraClrSchemeLst\" type=\"CT_ColorSchemeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custClrLst\" type=\"CT_CustomColorList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStylesOverride\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipboardStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"theme\" type=\"CT_OfficeStyleSheet\"/>\n  <xsd:element name=\"themeOverride\" type=\"CT_BaseStylesOverride\"/>\n  <xsd:element name=\"themeManager\" type=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_TableCellProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnL\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnR\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnT\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnB\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTlToBr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnBlToTr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marT\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"marB\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\" default=\"t\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\" default=\"clip\"\n    />\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"xsd:string\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCol\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableGrid\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TableCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCell\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TableCellProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rowSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"gridSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"hMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableRow\">\n    <xsd:sequence>\n      <xsd:element name=\"tc\" type=\"CT_TableCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"h\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\"/>\n        <xsd:element name=\"tableStyleId\" type=\"s:ST_Guid\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPr\" type=\"CT_TableProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TableGrid\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr\" type=\"CT_TableRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tbl\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Cell3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevel\" type=\"CT_Bevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\" default=\"plastic\"\n    />\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableFillStyle\">\n    <xsd:choice>\n      <xsd:element name=\"fill\" type=\"CT_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ThemeableLineStyle\">\n    <xsd:choice>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableEffectStyle\">\n    <xsd:choice>\n      <xsd:element name=\"effect\" type=\"CT_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ThemeableFontStyles\">\n    <xsd:choice>\n      <xsd:element name=\"font\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_OnOffStyleType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"def\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleTextStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFontStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"b\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n    <xsd:attribute name=\"i\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCellBorderStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"left\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideH\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideV\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableBackgroundStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableEffectStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleCellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcBdr\" type=\"CT_TableCellBorderStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePartStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcTxStyle\" type=\"CT_TableStyleTextStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcStyle\" type=\"CT_TableStyleCellStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tblBg\" type=\"CT_TableBackgroundStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wholeTbl\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"seCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"swCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"neCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nwCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"styleName\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"def\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"tblStyleLst\" type=\"CT_TableStyleList\"/>\n  <xsd:complexType name=\"CT_TextParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"endParaRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAnchoringType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"dist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVertOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"ellipsis\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextHorzOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVerticalType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"vert270\"/>\n      <xsd:enumeration value=\"wordArtVert\"/>\n      <xsd:enumeration value=\"eaVert\"/>\n      <xsd:enumeration value=\"mongolianVert\"/>\n      <xsd:enumeration value=\"wordArtVertRtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextWrappingType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"square\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextColumnCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"16\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextListStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"defPPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl1pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl2pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl3pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl4pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl5pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl6pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl7pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl8pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl9pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextFontScalePercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextFontScalePercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontScalePercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"1000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextNormalAutofit\">\n    <xsd:attribute name=\"fontScale\" type=\"ST_TextFontScalePercentOrPercentString\" use=\"optional\"\n      default=\"100%\"/>\n    <xsd:attribute name=\"lnSpcReduction\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"optional\"\n      default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextShapeAutofit\"/>\n  <xsd:complexType name=\"CT_TextNoAutofit\"/>\n  <xsd:group name=\"EG_TextAutofit\">\n    <xsd:choice>\n      <xsd:element name=\"noAutofit\" type=\"CT_TextNoAutofit\"/>\n      <xsd:element name=\"normAutofit\" type=\"CT_TextNormalAutofit\"/>\n      <xsd:element name=\"spAutoFit\" type=\"CT_TextShapeAutofit\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBodyProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextAutofit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"spcFirstLastPara\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"vertOverflow\" type=\"ST_TextVertOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_TextWrappingType\" use=\"optional\"/>\n    <xsd:attribute name=\"lIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"tIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"bIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"numCol\" type=\"ST_TextColumnCount\" use=\"optional\"/>\n    <xsd:attribute name=\"spcCol\" type=\"ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtlCol\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fromWordArt\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"forceAA\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"upright\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatLnSpc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBody\">\n    <xsd:sequence>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"p\" type=\"CT_TextParagraph\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextBulletStartAtNum\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"32767\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAutonumberScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"alphaLcParenBoth\"/>\n      <xsd:enumeration value=\"alphaUcParenBoth\"/>\n      <xsd:enumeration value=\"alphaLcParenR\"/>\n      <xsd:enumeration value=\"alphaUcParenR\"/>\n      <xsd:enumeration value=\"alphaLcPeriod\"/>\n      <xsd:enumeration value=\"alphaUcPeriod\"/>\n      <xsd:enumeration value=\"arabicParenBoth\"/>\n      <xsd:enumeration value=\"arabicParenR\"/>\n      <xsd:enumeration value=\"arabicPeriod\"/>\n      <xsd:enumeration value=\"arabicPlain\"/>\n      <xsd:enumeration value=\"romanLcParenBoth\"/>\n      <xsd:enumeration value=\"romanUcParenBoth\"/>\n      <xsd:enumeration value=\"romanLcParenR\"/>\n      <xsd:enumeration value=\"romanUcParenR\"/>\n      <xsd:enumeration value=\"romanLcPeriod\"/>\n      <xsd:enumeration value=\"romanUcPeriod\"/>\n      <xsd:enumeration value=\"circleNumDbPlain\"/>\n      <xsd:enumeration value=\"circleNumWdBlackPlain\"/>\n      <xsd:enumeration value=\"circleNumWdWhitePlain\"/>\n      <xsd:enumeration value=\"arabicDbPeriod\"/>\n      <xsd:enumeration value=\"arabicDbPlain\"/>\n      <xsd:enumeration value=\"ea1ChsPeriod\"/>\n      <xsd:enumeration value=\"ea1ChsPlain\"/>\n      <xsd:enumeration value=\"ea1ChtPeriod\"/>\n      <xsd:enumeration value=\"ea1ChtPlain\"/>\n      <xsd:enumeration value=\"ea1JpnChsDbPeriod\"/>\n      <xsd:enumeration value=\"ea1JpnKorPlain\"/>\n      <xsd:enumeration value=\"ea1JpnKorPeriod\"/>\n      <xsd:enumeration value=\"arabic1Minus\"/>\n      <xsd:enumeration value=\"arabic2Minus\"/>\n      <xsd:enumeration value=\"hebrew2Minus\"/>\n      <xsd:enumeration value=\"thaiAlphaPeriod\"/>\n      <xsd:enumeration value=\"thaiAlphaParenR\"/>\n      <xsd:enumeration value=\"thaiAlphaParenBoth\"/>\n      <xsd:enumeration value=\"thaiNumPeriod\"/>\n      <xsd:enumeration value=\"thaiNumParenR\"/>\n      <xsd:enumeration value=\"thaiNumParenBoth\"/>\n      <xsd:enumeration value=\"hindiAlphaPeriod\"/>\n      <xsd:enumeration value=\"hindiNumPeriod\"/>\n      <xsd:enumeration value=\"hindiNumParenR\"/>\n      <xsd:enumeration value=\"hindiAlpha1Period\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletColorFollowText\"/>\n  <xsd:group name=\"EG_TextBulletColor\">\n    <xsd:choice>\n      <xsd:element name=\"buClrTx\" type=\"CT_TextBulletColorFollowText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"buClr\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextBulletSize\">\n    <xsd:union memberTypes=\"ST_TextBulletSizePercent ST_TextBulletSizeDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*((2[5-9])|([3-9][0-9])|([1-3][0-9][0-9])|400)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizeDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"25000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletSizeFollowText\"/>\n  <xsd:complexType name=\"CT_TextBulletSizePercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextBulletSizePercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBulletSizePoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextFontSize\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextBulletSize\">\n    <xsd:choice>\n      <xsd:element name=\"buSzTx\" type=\"CT_TextBulletSizeFollowText\"/>\n      <xsd:element name=\"buSzPct\" type=\"CT_TextBulletSizePercent\"/>\n      <xsd:element name=\"buSzPts\" type=\"CT_TextBulletSizePoint\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBulletTypefaceFollowText\"/>\n  <xsd:group name=\"EG_TextBulletTypeface\">\n    <xsd:choice>\n      <xsd:element name=\"buFontTx\" type=\"CT_TextBulletTypefaceFollowText\"/>\n      <xsd:element name=\"buFont\" type=\"CT_TextFont\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextAutonumberBullet\">\n    <xsd:attribute name=\"type\" type=\"ST_TextAutonumberScheme\" use=\"required\"/>\n    <xsd:attribute name=\"startAt\" type=\"ST_TextBulletStartAtNum\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextCharBullet\">\n    <xsd:attribute name=\"char\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBlipBullet\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextNoBullet\"/>\n  <xsd:group name=\"EG_TextBullet\">\n    <xsd:choice>\n      <xsd:element name=\"buNone\" type=\"CT_TextNoBullet\"/>\n      <xsd:element name=\"buAutoNum\" type=\"CT_TextAutonumberBullet\"/>\n      <xsd:element name=\"buChar\" type=\"CT_TextCharBullet\"/>\n      <xsd:element name=\"buBlip\" type=\"CT_TextBlipBullet\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextPoint\">\n    <xsd:union memberTypes=\"ST_TextPointUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextPointUnqualified\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-400000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextNonNegativePoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontSize\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"100\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTypeface\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PitchFamily\">\n   <xsd:restriction base=\"xsd:byte\">\n     <xsd:enumeration value=\"00\"/>\n     <xsd:enumeration value=\"01\"/>\n     <xsd:enumeration value=\"02\"/>\n     <xsd:enumeration value=\"16\"/>\n     <xsd:enumeration value=\"17\"/>\n     <xsd:enumeration value=\"18\"/>\n     <xsd:enumeration value=\"32\"/>\n     <xsd:enumeration value=\"33\"/>\n     <xsd:enumeration value=\"34\"/>\n     <xsd:enumeration value=\"48\"/>\n     <xsd:enumeration value=\"49\"/>\n     <xsd:enumeration value=\"50\"/>\n     <xsd:enumeration value=\"64\"/>\n     <xsd:enumeration value=\"65\"/>\n     <xsd:enumeration value=\"66\"/>\n     <xsd:enumeration value=\"80\"/>\n     <xsd:enumeration value=\"81\"/>\n     <xsd:enumeration value=\"82\"/>\n   </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_TextFont\">\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n    <xsd:attribute name=\"panose\" type=\"s:ST_Panose\" use=\"optional\"/>\n    <xsd:attribute name=\"pitchFamily\" type=\"ST_PitchFamily\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"charset\" type=\"xsd:byte\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextUnderlineType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDashHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dotDotDashHeavy\"/>\n      <xsd:enumeration value=\"wavy\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDbl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextUnderlineLineFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillGroupWrapper\">\n    <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextUnderlineLine\">\n    <xsd:choice>\n      <xsd:element name=\"uLnTx\" type=\"CT_TextUnderlineLineFollowText\"/>\n      <xsd:element name=\"uLn\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextUnderlineFill\">\n    <xsd:choice>\n      <xsd:element name=\"uFillTx\" type=\"CT_TextUnderlineFillFollowText\"/>\n      <xsd:element name=\"uFill\" type=\"CT_TextUnderlineFillGroupWrapper\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextStrikeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"noStrike\"/>\n      <xsd:enumeration value=\"sngStrike\"/>\n      <xsd:enumeration value=\"dblStrike\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextCapsType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"small\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextCharacterProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineLine\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sym\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkMouseOver\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rtl\" type=\"CT_Boolean\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"kumimoji\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"altLang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_TextFontSize\" use=\"optional\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"u\" type=\"ST_TextUnderlineType\" use=\"optional\"/>\n    <xsd:attribute name=\"strike\" type=\"ST_TextStrikeType\" use=\"optional\"/>\n    <xsd:attribute name=\"kern\" type=\"ST_TextNonNegativePoint\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_TextCapsType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"spc\" type=\"ST_TextPoint\" use=\"optional\"/>\n    <xsd:attribute name=\"normalizeH\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"baseline\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"noProof\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"dirty\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"err\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"smtClean\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"smtId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bmk\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextSpacingPoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"158400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextSpacingPercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"13200000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextSpacingPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacingPoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPoint\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextMargin\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndent\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"-51206400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTabAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"dec\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextTabStop\">\n    <xsd:attribute name=\"pos\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextTabAlignType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextTabStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TextTabStop\" minOccurs=\"0\" maxOccurs=\"32\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLineBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacing\">\n    <xsd:choice>\n      <xsd:element name=\"spcPct\" type=\"CT_TextSpacingPercent\"/>\n      <xsd:element name=\"spcPts\" type=\"CT_TextSpacingPoint\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"justLow\"/>\n      <xsd:enumeration value=\"dist\"/>\n      <xsd:enumeration value=\"thaiDist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndentLevelType\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"8\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextParagraphProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnSpc\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcBef\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcAft\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletColor\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletTypeface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBullet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tabLst\" type=\"CT_TextTabStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"defRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"lvl\" type=\"ST_TextIndentLevelType\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"ST_TextIndent\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"defTabSz\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"eaLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fontAlgn\" type=\"ST_TextFontAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"latinLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingPunct\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextRun\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_RegularTextRun\"/>\n      <xsd:element name=\"br\" type=\"CT_TextLineBreak\"/>\n      <xsd:element name=\"fld\" type=\"CT_TextField\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RegularTextRun\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"shared-relationshipReference.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>\n  <xsd:element name=\"from\" type=\"CT_Marker\"/>\n  <xsd:element name=\"to\" type=\"CT_Marker\"/>\n  <xsd:complexType name=\"CT_AnchorClientData\">\n    <xsd:attribute name=\"fLocksWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPrintsWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ColID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RowID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"ST_ColID\"/>\n      <xsd:element name=\"colOff\" type=\"a:ST_Coordinate\"/>\n      <xsd:element name=\"row\" type=\"ST_RowID\"/>\n      <xsd:element name=\"rowOff\" type=\"a:ST_Coordinate\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"twoCell\"/>\n      <xsd:enumeration value=\"oneCell\"/>\n      <xsd:enumeration value=\"absolute\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TwoCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"editAs\" type=\"ST_EditAs\" use=\"optional\" default=\"twoCell\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OneCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsoluteAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"twoCellAnchor\" type=\"CT_TwoCellAnchor\"/>\n      <xsd:element name=\"oneCellAnchor\" type=\"CT_OneCellAnchor\"/>\n      <xsd:element name=\"absoluteAnchor\" type=\"CT_AbsoluteAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wsDr\" type=\"CT_Drawing\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:dpct=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"wml.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:complexType name=\"CT_EffectExtent\">\n    <xsd:attribute name=\"l\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapDistance\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Inline\">\n    <xsd:sequence>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapText\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bothSides\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WrapPath\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lineTo\" type=\"a:CT_Point2D\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"edited\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapNone\"/>\n  <xsd:complexType name=\"CT_WrapSquare\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTight\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapThrough\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTopBottom\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_WrapType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"wrapNone\" type=\"CT_WrapNone\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapSquare\" type=\"CT_WrapSquare\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTight\" type=\"CT_WrapTight\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapThrough\" type=\"CT_WrapThrough\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTopAndBottom\" type=\"CT_WrapTopBottom\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PositionOffset\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlignH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"leftMargin\"/>\n      <xsd:enumeration value=\"rightMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosH\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignH\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromH\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlignV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"topMargin\"/>\n      <xsd:enumeration value=\"bottomMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosV\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignV\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromV\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Anchor\">\n    <xsd:sequence>\n      <xsd:element name=\"simplePos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"positionH\" type=\"CT_PosH\"/>\n      <xsd:element name=\"positionV\" type=\"CT_PosV\"/>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_WrapType\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"simplePos\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"relativeHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"behindDoc\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"layoutInCell\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"allowOverlap\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"w:EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextboxInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinkedTextboxInformation\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"seq\" type=\"xsd:unsignedShort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingShape\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"cNvCnPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"txbx\" type=\"CT_TextboxInfo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"linkedTxbx\" type=\"CT_LinkedTextboxInformation\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"bodyPr\" type=\"a:CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"normalEastAsianFlow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvFrPr\" type=\"a:CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPartNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvContentPartPr\" type=\"a:CT_NonVisualContentPartProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPart\">\n    <xsd:sequence>\n      <xsd:element name=\"nvContentPartPr\" type=\"CT_WordprocessingContentPartNonVisual\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingGroup\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_WordprocessingGroup\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingCanvas\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n        <xsd:element ref=\"wgp\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wpc\" type=\"CT_WordprocessingCanvas\"/>\n  <xsd:element name=\"wgp\" type=\"CT_WordprocessingGroup\"/>\n  <xsd:element name=\"wsp\" type=\"CT_WordprocessingShape\"/>\n  <xsd:element name=\"inline\" type=\"CT_Inline\"/>\n  <xsd:element name=\"anchor\" type=\"CT_Anchor\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_TransitionSideDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"d\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionCornerDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"lu\"/>\n      <xsd:enumeration value=\"ru\"/>\n      <xsd:enumeration value=\"ld\"/>\n      <xsd:enumeration value=\"rd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionInOutDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SideDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionSideDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CornerDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionCornerDirectionType\" use=\"optional\" default=\"lu\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionEightDirectionType\">\n    <xsd:union memberTypes=\"ST_TransitionSideDirectionType ST_TransitionCornerDirectionType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EightDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionEightDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OrientationTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InOutTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptionalBlackTransition\">\n    <xsd:attribute name=\"thruBlk\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SplitTransition\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WheelTransition\">\n    <xsd:attribute name=\"spokes\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"4\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionStartSoundAction\">\n    <xsd:sequence>\n      <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"snd\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionSoundAction\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"stSnd\" type=\"CT_TransitionStartSoundAction\"/>\n      <xsd:element name=\"endSnd\" type=\"CT_Empty\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionSpeed\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slow\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"fast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideTransition\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"blinds\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"checker\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"circle\" type=\"CT_Empty\"/>\n        <xsd:element name=\"dissolve\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comb\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"cover\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"cut\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"diamond\" type=\"CT_Empty\"/>\n        <xsd:element name=\"fade\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"newsflash\" type=\"CT_Empty\"/>\n        <xsd:element name=\"plus\" type=\"CT_Empty\"/>\n        <xsd:element name=\"pull\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"push\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"random\" type=\"CT_Empty\"/>\n        <xsd:element name=\"randomBar\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"split\" type=\"CT_SplitTransition\"/>\n        <xsd:element name=\"strips\" type=\"CT_CornerDirectionTransition\"/>\n        <xsd:element name=\"wedge\" type=\"CT_Empty\"/>\n        <xsd:element name=\"wheel\" type=\"CT_WheelTransition\"/>\n        <xsd:element name=\"wipe\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"zoom\" type=\"CT_InOutTransition\"/>\n      </xsd:choice>\n      <xsd:element name=\"sndAc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TransitionSoundAction\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"spd\" type=\"ST_TransitionSpeed\" use=\"optional\" default=\"fast\"/>\n    <xsd:attribute name=\"advClick\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"advTm\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeIndefinite\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"indefinite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTime\">\n    <xsd:union memberTypes=\"xsd:unsignedInt ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeID\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateIntervalTime\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLIterateIntervalPercentage\">\n    <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_IterateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"el\"/>\n      <xsd:enumeration value=\"wd\"/>\n      <xsd:enumeration value=\"lt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateData\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"tmAbs\" type=\"CT_TLIterateIntervalTime\"/>\n      <xsd:element name=\"tmPct\" type=\"CT_TLIterateIntervalPercentage\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_IterateType\" use=\"optional\" default=\"el\"/>\n    <xsd:attribute name=\"backwards\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSubShapeId\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTextTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"charRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"pRg\" type=\"CT_IndexRange\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLChartSubelementType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"gridLegend\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleChartTargetElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TLChartSubelementType\" use=\"required\"/>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLShapeTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"CT_Empty\"/>\n      <xsd:element name=\"subSp\" type=\"CT_TLSubShapeId\"/>\n      <xsd:element name=\"oleChartEl\" type=\"CT_TLOleChartTargetElement\"/>\n      <xsd:element name=\"txEl\" type=\"CT_TLTextTargetElement\"/>\n      <xsd:element name=\"graphicEl\" type=\"a:CT_AnimationElementChoice\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeTargetElement\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"sldTgt\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sndTgt\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"spTgt\" type=\"CT_TLShapeTargetElement\"/>\n      <xsd:element name=\"inkTgt\" type=\"CT_TLSubShapeId\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTriggerTimeNodeID\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTimeNodeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerRuntimeNode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"first\"/>\n      <xsd:enumeration value=\"last\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTriggerRuntimeNode\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTriggerRuntimeNode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerEvent\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"onBegin\"/>\n      <xsd:enumeration value=\"onEnd\"/>\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"onClick\"/>\n      <xsd:enumeration value=\"onDblClick\"/>\n      <xsd:enumeration value=\"onMouseOver\"/>\n      <xsd:enumeration value=\"onMouseOut\"/>\n      <xsd:enumeration value=\"onNext\"/>\n      <xsd:enumeration value=\"onPrev\"/>\n      <xsd:enumeration value=\"onStopAudio\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeCondition\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\"/>\n      <xsd:element name=\"tn\" type=\"CT_TLTriggerTimeNodeID\"/>\n      <xsd:element name=\"rtn\" type=\"CT_TLTriggerRuntimeNode\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"evt\" use=\"optional\" type=\"ST_TLTriggerEvent\"/>\n    <xsd:attribute name=\"delay\" type=\"ST_TLTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeConditionList\">\n    <xsd:sequence>\n      <xsd:element name=\"cond\" type=\"CT_TLTimeCondition\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TimeNodeList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"par\" type=\"CT_TLTimeNodeParallel\"/>\n      <xsd:element name=\"seq\" type=\"CT_TLTimeNodeSequence\"/>\n      <xsd:element name=\"excl\" type=\"CT_TLTimeNodeExclusive\"/>\n      <xsd:element name=\"anim\" type=\"CT_TLAnimateBehavior\"/>\n      <xsd:element name=\"animClr\" type=\"CT_TLAnimateColorBehavior\"/>\n      <xsd:element name=\"animEffect\" type=\"CT_TLAnimateEffectBehavior\"/>\n      <xsd:element name=\"animMotion\" type=\"CT_TLAnimateMotionBehavior\"/>\n      <xsd:element name=\"animRot\" type=\"CT_TLAnimateRotationBehavior\"/>\n      <xsd:element name=\"animScale\" type=\"CT_TLAnimateScaleBehavior\"/>\n      <xsd:element name=\"cmd\" type=\"CT_TLCommandBehavior\"/>\n      <xsd:element name=\"set\" type=\"CT_TLSetBehavior\"/>\n      <xsd:element name=\"audio\" type=\"CT_TLMediaNodeAudio\"/>\n      <xsd:element name=\"video\" type=\"CT_TLMediaNodeVideo\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeNodePresetClassType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"entr\"/>\n      <xsd:enumeration value=\"exit\"/>\n      <xsd:enumeration value=\"emph\"/>\n      <xsd:enumeration value=\"path\"/>\n      <xsd:enumeration value=\"verb\"/>\n      <xsd:enumeration value=\"mediacall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeRestartType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"whenNotActive\"/>\n      <xsd:enumeration value=\"never\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeFillType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"remove\"/>\n      <xsd:enumeration value=\"freeze\"/>\n      <xsd:enumeration value=\"hold\"/>\n      <xsd:enumeration value=\"transition\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeSyncType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"canSlip\"/>\n      <xsd:enumeration value=\"locked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeMasterRelation\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sameClick\"/>\n      <xsd:enumeration value=\"lastClick\"/>\n      <xsd:enumeration value=\"nextClick\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clickEffect\"/>\n      <xsd:enumeration value=\"withEffect\"/>\n      <xsd:enumeration value=\"afterEffect\"/>\n      <xsd:enumeration value=\"mainSeq\"/>\n      <xsd:enumeration value=\"interactiveSeq\"/>\n      <xsd:enumeration value=\"clickPar\"/>\n      <xsd:enumeration value=\"withGroup\"/>\n      <xsd:enumeration value=\"afterGroup\"/>\n      <xsd:enumeration value=\"tmRoot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonTimeNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"stCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endSync\" type=\"CT_TLTimeCondition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iterate\" type=\"CT_TLIterateData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"childTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"subTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_TLTimeNodeID\" use=\"optional\"/>\n    <xsd:attribute name=\"presetID\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presetClass\" type=\"ST_TLTimeNodePresetClassType\" use=\"optional\"/>\n    <xsd:attribute name=\"presetSubtype\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"dur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"repeatCount\" type=\"ST_TLTime\" use=\"optional\" default=\"1000\"/>\n    <xsd:attribute name=\"repeatDur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"spd\" type=\"a:ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"accel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"decel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"autoRev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_TLTimeNodeRestartType\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_TLTimeNodeFillType\" use=\"optional\"/>\n    <xsd:attribute name=\"syncBehavior\" type=\"ST_TLTimeNodeSyncType\" use=\"optional\"/>\n    <xsd:attribute name=\"tmFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"evtFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"masterRel\" type=\"ST_TLTimeNodeMasterRelation\" use=\"optional\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"afterEffect\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nodeType\" type=\"ST_TLTimeNodeType\" use=\"optional\"/>\n    <xsd:attribute name=\"nodePh\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeParallel\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLNextActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"seek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLPreviousActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"skipTimed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeNodeSequence\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prevCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nextCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"concurrent\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"prevAc\" type=\"ST_TLPreviousActionType\" use=\"optional\"/>\n    <xsd:attribute name=\"nextAc\" type=\"ST_TLNextActionType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeExclusive\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLBehaviorAttributeNameList\">\n    <xsd:sequence>\n      <xsd:element name=\"attrName\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLBehaviorAdditiveType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"repl\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorAccumulateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorTransformType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pt\"/>\n      <xsd:enumeration value=\"img\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorOverrideType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"childStyle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonBehaviorData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attrNameLst\" type=\"CT_TLBehaviorAttributeNameList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"additive\" type=\"ST_TLBehaviorAdditiveType\" use=\"optional\"/>\n    <xsd:attribute name=\"accumulate\" type=\"ST_TLBehaviorAccumulateType\" use=\"optional\"/>\n    <xsd:attribute name=\"xfrmType\" type=\"ST_TLBehaviorTransformType\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rctx\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"override\" type=\"ST_TLBehaviorOverrideType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantBooleanVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantIntegerVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantFloatVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:float\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantStringVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"boolVal\" type=\"CT_TLAnimVariantBooleanVal\"/>\n      <xsd:element name=\"intVal\" type=\"CT_TLAnimVariantIntegerVal\"/>\n      <xsd:element name=\"fltVal\" type=\"CT_TLAnimVariantFloatVal\"/>\n      <xsd:element name=\"strVal\" type=\"CT_TLAnimVariantStringVal\"/>\n      <xsd:element name=\"clrVal\" type=\"a:CT_Color\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeAnimateValueTime\">\n    <xsd:union memberTypes=\"a:ST_PositiveFixedPercentage ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tm\" type=\"ST_TLTimeAnimateValueTime\" use=\"optional\" default=\"indefinite\"/>\n    <xsd:attribute name=\"fmla\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValueList\">\n    <xsd:sequence>\n      <xsd:element name=\"tav\" type=\"CT_TLTimeAnimateValue\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorCalcMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"discrete\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"fmla\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorValueType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tavLst\" type=\"CT_TLTimeAnimateValueList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"calcmode\" type=\"ST_TLAnimateBehaviorCalcMode\" use=\"optional\"/>\n    <xsd:attribute name=\"valueType\" type=\"ST_TLAnimateBehaviorValueType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByRgbColorTransform\">\n    <xsd:attribute name=\"r\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByHslColorTransform\">\n    <xsd:attribute name=\"h\" type=\"a:ST_Angle\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"l\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByAnimateColorTransform\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"rgb\" type=\"CT_TLByRgbColorTransform\"/>\n      <xsd:element name=\"hsl\" type=\"CT_TLByHslColorTransform\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateColorSpace\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rgb\"/>\n      <xsd:enumeration value=\"hsl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateColorDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateColorBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLByAnimateColorTransform\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"clrSpc\" type=\"ST_TLAnimateColorSpace\" use=\"optional\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TLAnimateColorDirection\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateEffectTransition\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateEffectBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"progress\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"transition\" type=\"ST_TLAnimateEffectTransition\" default=\"in\" use=\"optional\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"prLst\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionBehaviorOrigin\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parent\"/>\n      <xsd:enumeration value=\"layout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionPathEditMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relative\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLPoint\">\n    <xsd:attribute name=\"x\" type=\"a:ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"a:ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateMotionBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rCtr\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"origin\" type=\"ST_TLAnimateMotionBehaviorOrigin\" use=\"optional\"/>\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"pathEditMode\" type=\"ST_TLAnimateMotionPathEditMode\" use=\"optional\"/>\n    <xsd:attribute name=\"rAng\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"ptsTypes\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateRotationBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"a:ST_Angle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateScaleBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zoomContents\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLCommandType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"evt\"/>\n      <xsd:enumeration value=\"call\"/>\n      <xsd:enumeration value=\"verb\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommandBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute type=\"ST_TLCommandType\" name=\"type\" use=\"optional\"/>\n    <xsd:attribute name=\"cmd\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSetBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLCommonMediaNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"vol\" type=\"a:ST_PositiveFixedPercentage\" default=\"50%\" use=\"optional\"/>\n    <xsd:attribute name=\"mute\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numSld\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showWhenStopped\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeAudio\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeVideo\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullScrn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_TLBuild\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uiExpand\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_TLTemplate\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTemplateList\">\n    <xsd:sequence>\n      <xsd:element name=\"tmpl\" type=\"CT_TLTemplate\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLParaBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"whole\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"tmplLst\" type=\"CT_TLTemplateList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"build\" type=\"ST_TLParaBuildType\" use=\"optional\" default=\"whole\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoUpdateAnimBg\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advAuto\" type=\"ST_TLTime\" use=\"optional\" default=\"indefinite\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLDiagramBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"depthByNode\"/>\n      <xsd:enumeration value=\"depthByBranch\"/>\n      <xsd:enumeration value=\"breadthByNode\"/>\n      <xsd:enumeration value=\"breadthByLvl\"/>\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"cwIn\"/>\n      <xsd:enumeration value=\"cwOut\"/>\n      <xsd:enumeration value=\"ccw\"/>\n      <xsd:enumeration value=\"ccwIn\"/>\n      <xsd:enumeration value=\"ccwOut\"/>\n      <xsd:enumeration value=\"inByRing\"/>\n      <xsd:enumeration value=\"outByRing\"/>\n      <xsd:enumeration value=\"up\"/>\n      <xsd:enumeration value=\"down\"/>\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildDiagram\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLDiagramBuildType\" use=\"optional\" default=\"whole\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLOleChartBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleBuildChart\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLOleChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLGraphicalObjectBuild\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bldAsOne\" type=\"CT_Empty\"/>\n      <xsd:element name=\"bldSub\" type=\"a:CT_AnimationGraphicalObjectBuildProperties\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BuildList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bldP\" type=\"CT_TLBuildParagraph\"/>\n      <xsd:element name=\"bldDgm\" type=\"CT_TLBuildDiagram\"/>\n      <xsd:element name=\"bldOleChart\" type=\"CT_TLOleBuildChart\"/>\n      <xsd:element name=\"bldGraphic\" type=\"CT_TLGraphicalObjectBuild\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideTiming\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bldLst\" type=\"CT_BuildList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:simpleType name=\"ST_Name\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IndexRange\">\n    <xsd:attribute name=\"st\" type=\"ST_Index\" use=\"required\"/>\n    <xsd:attribute name=\"end\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipListEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_SlideRelationshipListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowId\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SlideListChoice\">\n    <xsd:choice>\n      <xsd:element name=\"sldAll\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sldRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShowId\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CustomerData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagsData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomerDataList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"custData\" type=\"CT_CustomerData\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tags\" type=\"CT_TagsData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionListModify\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mod\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthor\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"initials\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"lastIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"clrIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthorList\">\n    <xsd:sequence>\n      <xsd:element name=\"cmAuthor\" type=\"CT_CommentAuthor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmAuthorLst\" type=\"CT_CommentAuthorList\"/>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"text\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"idx\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"cm\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmLst\" type=\"CT_CommentList\"/>\n  <xsd:attributeGroup name=\"AG_Ole\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"showAsIcon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"imgW\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"imgH\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:simpleType name=\"ST_OleObjectFollowColorScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"textAndBackground\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleObjectEmbed\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"followColorScheme\" type=\"ST_OleObjectFollowColorScheme\" use=\"optional\"\n      default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjectLink\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"updateAutomatic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"embed\" type=\"CT_OleObjectEmbed\"/>\n        <xsd:element name=\"link\" type=\"CT_OleObjectLink\"/>\n      </xsd:choice>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"oleObj\" type=\"CT_OleObject\"/>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlList\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"256\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideId\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldId\" type=\"CT_SlideIdListEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideMasterId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideMasterId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterId\" type=\"CT_SlideMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"notesMasterId\" type=\"CT_NotesMasterIdListEntry\" minOccurs=\"0\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"handoutMasterId\" type=\"CT_HandoutMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontDataId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"a:CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"regular\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bold\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"italic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"boldItalic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontList\">\n    <xsd:sequence>\n      <xsd:element name=\"embeddedFont\" type=\"CT_EmbeddedFontListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShow\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLst\" type=\"CT_SlideRelationshipList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowList\">\n    <xsd:sequence>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhotoAlbumLayout\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fitToSlide\"/>\n      <xsd:enumeration value=\"1pic\"/>\n      <xsd:enumeration value=\"2pic\"/>\n      <xsd:enumeration value=\"4pic\"/>\n      <xsd:enumeration value=\"1picTitle\"/>\n      <xsd:enumeration value=\"2picTitle\"/>\n      <xsd:enumeration value=\"4picTitle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhotoAlbumFrameShape\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"frameStyle1\"/>\n      <xsd:enumeration value=\"frameStyle2\"/>\n      <xsd:enumeration value=\"frameStyle3\"/>\n      <xsd:enumeration value=\"frameStyle4\"/>\n      <xsd:enumeration value=\"frameStyle5\"/>\n      <xsd:enumeration value=\"frameStyle6\"/>\n      <xsd:enumeration value=\"frameStyle7\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhotoAlbum\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bw\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showCaptions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"layout\" type=\"ST_PhotoAlbumLayout\" use=\"optional\" default=\"fitToSlide\"/>\n    <xsd:attribute name=\"frame\" type=\"ST_PhotoAlbumFrameShape\" use=\"optional\" default=\"frameStyle1\"\n    />\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideSizeCoordinate\">\n    <xsd:restriction base=\"a:ST_PositiveCoordinate32\">\n      <xsd:minInclusive value=\"914400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SlideSizeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"screen4x3\"/>\n      <xsd:enumeration value=\"letter\"/>\n      <xsd:enumeration value=\"A4\"/>\n      <xsd:enumeration value=\"35mm\"/>\n      <xsd:enumeration value=\"overhead\"/>\n      <xsd:enumeration value=\"banner\"/>\n      <xsd:enumeration value=\"custom\"/>\n      <xsd:enumeration value=\"ledger\"/>\n      <xsd:enumeration value=\"A3\"/>\n      <xsd:enumeration value=\"B4ISO\"/>\n      <xsd:enumeration value=\"B5ISO\"/>\n      <xsd:enumeration value=\"B4JIS\"/>\n      <xsd:enumeration value=\"B5JIS\"/>\n      <xsd:enumeration value=\"hagakiCard\"/>\n      <xsd:enumeration value=\"screen16x9\"/>\n      <xsd:enumeration value=\"screen16x10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideSize\">\n    <xsd:attribute name=\"cx\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideSizeType\" use=\"optional\" default=\"custom\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"invalStChars\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"invalEndChars\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BookmarkIdSeed\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ModifyVerifier\">\n    <xsd:attribute name=\"algorithmName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinValue\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"saltData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"hashData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Presentation\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterIdLst\" type=\"CT_SlideMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesMasterIdLst\" type=\"CT_NotesMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"handoutMasterIdLst\" type=\"CT_HandoutMasterIdList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sldIdLst\" type=\"CT_SlideIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldSz\" type=\"CT_SlideSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesSz\" type=\"a:CT_PositiveSize2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embeddedFontLst\" type=\"CT_EmbeddedFontList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custShowLst\" type=\"CT_CustomShowList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"photoAlbum\" type=\"CT_PhotoAlbum\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTextStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"modifyVerifier\" type=\"CT_ModifyVerifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverZoom\" type=\"a:ST_Percentage\" use=\"optional\" default=\"50%\"/>\n    <xsd:attribute name=\"firstSlideNum\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showSpecialPlsOnTitleSld\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removePersonalInfoOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"strictFirstAndLastChars\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"embedTrueTypeFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveSubsetFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"bookmarkIdSeed\" type=\"ST_BookmarkIdSeed\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:element name=\"presentation\" type=\"CT_Presentation\"/>\n  <xsd:complexType name=\"CT_HtmlPublishProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showSpeakerNotes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebColorType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"browser\"/>\n      <xsd:enumeration value=\"presentationText\"/>\n      <xsd:enumeration value=\"presentationAccent\"/>\n      <xsd:enumeration value=\"whiteTextOnBlack\"/>\n      <xsd:enumeration value=\"blackTextOnWhite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebScreenSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1400\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebEncoding\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"resizeGraphics\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"relyOnVml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"organizeInFolders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useLongFilenames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"imgSz\" type=\"ST_WebScreenSize\" use=\"optional\" default=\"800x600\"/>\n    <xsd:attribute name=\"encoding\" type=\"ST_WebEncoding\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"clr\" type=\"ST_WebColorType\" use=\"optional\" default=\"whiteTextOnBlack\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintWhat\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slides\"/>\n      <xsd:enumeration value=\"handouts1\"/>\n      <xsd:enumeration value=\"handouts2\"/>\n      <xsd:enumeration value=\"handouts3\"/>\n      <xsd:enumeration value=\"handouts4\"/>\n      <xsd:enumeration value=\"handouts6\"/>\n      <xsd:enumeration value=\"handouts9\"/>\n      <xsd:enumeration value=\"notes\"/>\n      <xsd:enumeration value=\"outline\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrintColorMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bw\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PrintProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prnWhat\" type=\"ST_PrintWhat\" use=\"optional\" default=\"slides\"/>\n    <xsd:attribute name=\"clrMode\" type=\"ST_PrintColorMode\" use=\"optional\" default=\"clr\"/>\n    <xsd:attribute name=\"hiddenSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scaleToFitPaper\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"frameSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoBrowse\">\n    <xsd:attribute name=\"showScrollbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoKiosk\">\n    <xsd:attribute name=\"restart\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"300000\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShowType\">\n    <xsd:choice>\n      <xsd:element name=\"present\" type=\"CT_Empty\"/>\n      <xsd:element name=\"browse\" type=\"CT_ShowInfoBrowse\"/>\n      <xsd:element name=\"kiosk\" type=\"CT_ShowInfoKiosk\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ShowProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:group ref=\"EG_ShowType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"penClr\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useTimings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"htmlPubPr\" type=\"CT_HtmlPublishProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPr\" type=\"CT_WebProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prnPr\" type=\"CT_PrintProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPr\" type=\"CT_ShowProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMru\" type=\"a:CT_ColorMRU\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"presentationPr\" type=\"CT_PresentationProperties\"/>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sldNum\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"hdr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"ftr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PlaceholderType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"body\"/>\n      <xsd:enumeration value=\"ctrTitle\"/>\n      <xsd:enumeration value=\"subTitle\"/>\n      <xsd:enumeration value=\"dt\"/>\n      <xsd:enumeration value=\"sldNum\"/>\n      <xsd:enumeration value=\"ftr\"/>\n      <xsd:enumeration value=\"hdr\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"clipArt\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"media\"/>\n      <xsd:enumeration value=\"sldImg\"/>\n      <xsd:enumeration value=\"pic\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PlaceholderSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"half\"/>\n      <xsd:enumeration value=\"quarter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_PlaceholderType\" use=\"optional\" default=\"obj\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_PlaceholderSize\" use=\"optional\" default=\"full\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hasCustomPrompt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ApplicationNonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"ph\" type=\"CT_Placeholder\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_Media\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isPhoto\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useBgFill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TopLevelSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMap\" type=\"a:CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_ChildSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMappingOverride\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_ChildSlide\">\n    <xsd:attribute name=\"showMasterSp\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showMasterPhAnim\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_BackgroundProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shadeToTitle\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Background\">\n    <xsd:choice>\n      <xsd:element name=\"bgPr\" type=\"CT_BackgroundProperties\"/>\n      <xsd:element name=\"bgRef\" type=\"a:CT_StyleMatrixReference\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Background\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\" default=\"white\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideData\">\n    <xsd:sequence>\n      <xsd:element name=\"bg\" type=\"CT_Background\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spTree\" type=\"CT_GroupShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_ControlList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Slide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sld\" type=\"CT_Slide\"/>\n  <xsd:simpleType name=\"ST_SlideLayoutType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"twoColTx\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"txAndChart\"/>\n      <xsd:enumeration value=\"chartAndTx\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"txAndClipArt\"/>\n      <xsd:enumeration value=\"clipArtAndTx\"/>\n      <xsd:enumeration value=\"titleOnly\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"txAndObj\"/>\n      <xsd:enumeration value=\"objAndTx\"/>\n      <xsd:enumeration value=\"objOnly\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"txAndMedia\"/>\n      <xsd:enumeration value=\"mediaAndTx\"/>\n      <xsd:enumeration value=\"objOverTx\"/>\n      <xsd:enumeration value=\"txOverObj\"/>\n      <xsd:enumeration value=\"txAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndTx\"/>\n      <xsd:enumeration value=\"twoObjOverTx\"/>\n      <xsd:enumeration value=\"fourObj\"/>\n      <xsd:enumeration value=\"vertTx\"/>\n      <xsd:enumeration value=\"clipArtAndVertTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTxOverChart\"/>\n      <xsd:enumeration value=\"twoObj\"/>\n      <xsd:enumeration value=\"objAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndObj\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"secHead\"/>\n      <xsd:enumeration value=\"twoTxTwoObj\"/>\n      <xsd:enumeration value=\"objTx\"/>\n      <xsd:enumeration value=\"picTx\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayout\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"matchingName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideLayoutType\" use=\"optional\" default=\"cust\"/>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldLayout\" type=\"CT_SlideLayout\"/>\n  <xsd:complexType name=\"CT_SlideMasterTextStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"titleStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"otherStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideLayoutId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayoutIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideLayoutId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideLayoutIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLayoutId\" type=\"CT_SlideLayoutIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMaster\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLayoutIdLst\" type=\"CT_SlideLayoutIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txStyles\" type=\"CT_SlideMasterTextStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldMaster\" type=\"CT_SlideMaster\"/>\n  <xsd:complexType name=\"CT_HandoutMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"handoutMaster\" type=\"CT_HandoutMaster\"/>\n  <xsd:complexType name=\"CT_NotesMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"notesMaster\" type=\"CT_NotesMaster\"/>\n  <xsd:complexType name=\"CT_NotesSlide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n  </xsd:complexType>\n  <xsd:element name=\"notes\" type=\"CT_NotesSlide\"/>\n  <xsd:complexType name=\"CT_SlideSyncProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverSldId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"serverSldModifiedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"clientInsertedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldSyncPr\" type=\"CT_SlideSyncProperties\"/>\n  <xsd:complexType name=\"CT_StringTag\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagList\">\n    <xsd:sequence>\n      <xsd:element name=\"tag\" type=\"CT_StringTag\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tagLst\" type=\"CT_TagList\"/>\n  <xsd:simpleType name=\"ST_SplitterBarState\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"minimized\"/>\n      <xsd:enumeration value=\"restored\"/>\n      <xsd:enumeration value=\"maximized\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ViewType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sldView\"/>\n      <xsd:enumeration value=\"sldMasterView\"/>\n      <xsd:enumeration value=\"notesView\"/>\n      <xsd:enumeration value=\"handoutView\"/>\n      <xsd:enumeration value=\"notesMasterView\"/>\n      <xsd:enumeration value=\"outlineView\"/>\n      <xsd:enumeration value=\"sldSorterView\"/>\n      <xsd:enumeration value=\"sldThumbnailView\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NormalViewPortion\">\n    <xsd:attribute name=\"sz\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"autoAdjust\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NormalViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"restoredLeft\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"restoredTop\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showOutlineIcons\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapVertSplitter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vertBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"horzBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"preferSingleView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"scale\" type=\"a:CT_Scale2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"origin\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"varScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesTextViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"collapse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_OutlineViewSlideEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLst\" type=\"CT_OutlineViewSlideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideSorterViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guide\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"vert\"/>\n    <xsd:attribute name=\"pos\" type=\"a:ST_Coordinate32\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GuideList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"guide\" type=\"CT_Guide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"guideLst\" type=\"CT_GuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"snapToGrid\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapToObjects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGuides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ViewProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"normalViewPr\" type=\"CT_NormalViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"slideViewPr\" type=\"CT_SlideViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlineViewPr\" type=\"CT_OutlineViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesTextViewPr\" type=\"CT_NotesTextViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sorterViewPr\" type=\"CT_SlideSorterViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"notesViewPr\" type=\"CT_NotesViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpacing\" type=\"a:CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastView\" type=\"ST_ViewType\" use=\"optional\" default=\"sldView\"/>\n    <xsd:attribute name=\"showComments\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"viewPr\" type=\"CT_ViewProperties\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_AdditionalCharacteristics\">\n    <xsd:sequence>\n      <xsd:element name=\"characteristic\" type=\"CT_Characteristic\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Characteristic\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"relation\" type=\"ST_Relation\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"vocabulary\" type=\"xsd:anyURI\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Relation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ge\"/>\n      <xsd:enumeration value=\"le\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"eq\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"additionalCharacteristics\" type=\"CT_AdditionalCharacteristics\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"s:ST_String\">\n      <xsd:enumeration value=\"ArticleInAPeriodical\"/>\n      <xsd:enumeration value=\"Book\"/>\n      <xsd:enumeration value=\"BookSection\"/>\n      <xsd:enumeration value=\"JournalArticle\"/>\n      <xsd:enumeration value=\"ConferenceProceedings\"/>\n      <xsd:enumeration value=\"Report\"/>\n      <xsd:enumeration value=\"SoundRecording\"/>\n      <xsd:enumeration value=\"Performance\"/>\n      <xsd:enumeration value=\"Art\"/>\n      <xsd:enumeration value=\"DocumentFromInternetSite\"/>\n      <xsd:enumeration value=\"InternetSite\"/>\n      <xsd:enumeration value=\"Film\"/>\n      <xsd:enumeration value=\"Interview\"/>\n      <xsd:enumeration value=\"Patent\"/>\n      <xsd:enumeration value=\"ElectronicSource\"/>\n      <xsd:enumeration value=\"Case\"/>\n      <xsd:enumeration value=\"Misc\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NameListType\">\n    <xsd:sequence>\n      <xsd:element name=\"Person\" type=\"CT_PersonType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PersonType\">\n    <xsd:sequence>\n      <xsd:element name=\"Last\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"First\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Middle\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameType\">\n    <xsd:sequence>\n      <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameOrCorporateType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"Corporate\" minOccurs=\"1\" maxOccurs=\"1\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AuthorType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"Artist\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Author\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"BookAuthor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Compiler\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Composer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Conductor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Counsel\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Director\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Editor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewee\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Inventor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Performer\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"ProducerName\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Translator\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Writer\" type=\"CT_NameType\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SourceType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"AbbreviatedCaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"AlbumTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Author\" type=\"CT_AuthorType\"/>\n        <xsd:element name=\"BookTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Broadcaster\" type=\"s:ST_String\"/>\n        <xsd:element name=\"BroadcastTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ChapterNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"City\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Comments\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ConferenceName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CountryRegion\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Court\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Day\" type=\"s:ST_String\"/>\n        <xsd:element name=\"DayAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Department\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Distributor\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Edition\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Guid\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Institution\" type=\"s:ST_String\"/>\n        <xsd:element name=\"InternetSiteTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Issue\" type=\"s:ST_String\"/>\n        <xsd:element name=\"JournalName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"LCID\" type=\"s:ST_Lang\"/>\n        <xsd:element name=\"Medium\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Month\" type=\"s:ST_String\"/>\n        <xsd:element name=\"MonthAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"NumberVolumes\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Pages\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PatentNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PeriodicalTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ProductionCompany\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PublicationTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Publisher\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RecordingNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RefOrder\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Reporter\" type=\"s:ST_String\"/>\n        <xsd:element name=\"SourceType\" type=\"ST_SourceType\"/>\n        <xsd:element name=\"ShortTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StandardNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StateProvince\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Station\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Tag\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Theater\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ThesisType\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Title\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Type\" type=\"s:ST_String\"/>\n        <xsd:element name=\"URL\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Version\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Volume\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Year\" type=\"s:ST_String\"/>\n        <xsd:element name=\"YearAccessed\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"Sources\" type=\"CT_Sources\"/>\n  <xsd:complexType name=\"CT_Sources\">\n    <xsd:sequence>\n      <xsd:element name=\"Source\" type=\"CT_SourceType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectedStyle\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"StyleName\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"URI\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\">\n  <xsd:simpleType name=\"ST_Lang\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColorRGB\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"3\" fixed=\"true\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Panose\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalendarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gregorian\"/>\n      <xsd:enumeration value=\"gregorianUs\"/>\n      <xsd:enumeration value=\"gregorianMeFrench\"/>\n      <xsd:enumeration value=\"gregorianArabic\"/>\n      <xsd:enumeration value=\"hijri\"/>\n      <xsd:enumeration value=\"hebrew\"/>\n      <xsd:enumeration value=\"taiwan\"/>\n      <xsd:enumeration value=\"japan\"/>\n      <xsd:enumeration value=\"thai\"/>\n      <xsd:enumeration value=\"korea\"/>\n      <xsd:enumeration value=\"saka\"/>\n      <xsd:enumeration value=\"gregorianXlitEnglish\"/>\n      <xsd:enumeration value=\"gregorianXlitFrench\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hash\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CryptProv\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rsaAES\"/>\n      <xsd:enumeration value=\"rsaFull\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"typeAny\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Guid\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff\">\n    <xsd:union memberTypes=\"xsd:boolean ST_OnOff1\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff1\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_String\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XmlName\">\n    <xsd:restriction base=\"xsd:NCName\">\n      <xsd:minLength value=\"1\"/>\n      <xsd:maxLength value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalse\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalseBlank\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n      <xsd:enumeration value=\"\"/>\n      <xsd:enumeration value=\"True\"/>\n      <xsd:enumeration value=\"False\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedDecimalNumber\">\n    <xsd:restriction base=\"xsd:decimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TwipsMeasure\">\n    <xsd:union memberTypes=\"ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignRun\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"superscript\"/>\n      <xsd:enumeration value=\"subscript\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Xstring\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_YAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inline\"/>\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConformanceClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"strict\"/>\n      <xsd:enumeration value=\"transitional\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UniversalMeasure\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveUniversalMeasure\">\n    <xsd:restriction base=\"ST_UniversalMeasure\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"-?((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_DatastoreSchemaRef\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreSchemaRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRef\" type=\"CT_DatastoreSchemaRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreItem\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRefs\" type=\"CT_DatastoreSchemaRefs\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"itemID\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"datastoreItem\" type=\"CT_DatastoreItem\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_Schema\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" default=\"\"/>\n    <xsd:attribute name=\"manifestLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLanguage\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SchemaLibrary\">\n    <xsd:sequence>\n      <xsd:element name=\"schema\" type=\"CT_Schema\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"schemaLibrary\" type=\"CT_SchemaLibrary\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:sequence>\n      <xsd:element name=\"property\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Property\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Property\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n      <xsd:element ref=\"vt:array\"/>\n      <xsd:element ref=\"vt:blob\"/>\n      <xsd:element ref=\"vt:oblob\"/>\n      <xsd:element ref=\"vt:empty\"/>\n      <xsd:element ref=\"vt:null\"/>\n      <xsd:element ref=\"vt:i1\"/>\n      <xsd:element ref=\"vt:i2\"/>\n      <xsd:element ref=\"vt:i4\"/>\n      <xsd:element ref=\"vt:i8\"/>\n      <xsd:element ref=\"vt:int\"/>\n      <xsd:element ref=\"vt:ui1\"/>\n      <xsd:element ref=\"vt:ui2\"/>\n      <xsd:element ref=\"vt:ui4\"/>\n      <xsd:element ref=\"vt:ui8\"/>\n      <xsd:element ref=\"vt:uint\"/>\n      <xsd:element ref=\"vt:r4\"/>\n      <xsd:element ref=\"vt:r8\"/>\n      <xsd:element ref=\"vt:decimal\"/>\n      <xsd:element ref=\"vt:lpstr\"/>\n      <xsd:element ref=\"vt:lpwstr\"/>\n      <xsd:element ref=\"vt:bstr\"/>\n      <xsd:element ref=\"vt:date\"/>\n      <xsd:element ref=\"vt:filetime\"/>\n      <xsd:element ref=\"vt:bool\"/>\n      <xsd:element ref=\"vt:cy\"/>\n      <xsd:element ref=\"vt:error\"/>\n      <xsd:element ref=\"vt:stream\"/>\n      <xsd:element ref=\"vt:ostream\"/>\n      <xsd:element ref=\"vt:storage\"/>\n      <xsd:element ref=\"vt:ostorage\"/>\n      <xsd:element ref=\"vt:vstream\"/>\n      <xsd:element ref=\"vt:clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fmtid\" use=\"required\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"pid\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"linkTarget\" use=\"optional\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  elementFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:all>\n      <xsd:element name=\"Template\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Manager\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Company\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Pages\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Words\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Characters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"PresentationFormat\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Lines\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Paragraphs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Slides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Notes\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"TotalTime\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"HiddenSlides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"MMClips\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"ScaleCrop\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HeadingPairs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"TitlesOfParts\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorLpstr\"/>\n      <xsd:element name=\"LinksUpToDate\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"CharactersWithSpaces\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"SharedDoc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HyperlinkBase\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"HLinks\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"HyperlinksChanged\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"DigSig\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DigSigBlob\"/>\n      <xsd:element name=\"Application\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"AppVersion\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"DocSecurity\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorVariant\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorLpstr\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DigSigBlob\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:blob\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_VectorBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"i8\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"ui8\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"lpstr\"/>\n      <xsd:enumeration value=\"lpwstr\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"filetime\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n      <xsd:enumeration value=\"clsid\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrayBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"int\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"uint\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Cy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*[0-9]*\\.[0-9]{4}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Error\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*0x[0-9A-Za-z]{8}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Null\"/>\n  <xsd:complexType name=\"CT_Vector\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"baseType\" type=\"ST_VectorBaseType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Array\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"cy\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"lBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"uBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"baseType\" type=\"ST_ArrayBaseType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Variant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"vector\"/>\n      <xsd:element ref=\"array\"/>\n      <xsd:element ref=\"blob\"/>\n      <xsd:element ref=\"oblob\"/>\n      <xsd:element ref=\"empty\"/>\n      <xsd:element ref=\"null\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"stream\"/>\n      <xsd:element ref=\"ostream\"/>\n      <xsd:element ref=\"storage\"/>\n      <xsd:element ref=\"ostorage\"/>\n      <xsd:element ref=\"vstream\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vstream\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:base64Binary\">\n        <xsd:attribute name=\"version\" type=\"s:ST_Guid\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:element name=\"variant\" type=\"CT_Variant\"/>\n  <xsd:element name=\"vector\" type=\"CT_Vector\"/>\n  <xsd:element name=\"array\" type=\"CT_Array\"/>\n  <xsd:element name=\"blob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"oblob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"empty\" type=\"CT_Empty\"/>\n  <xsd:element name=\"null\" type=\"CT_Null\"/>\n  <xsd:element name=\"i1\" type=\"xsd:byte\"/>\n  <xsd:element name=\"i2\" type=\"xsd:short\"/>\n  <xsd:element name=\"i4\" type=\"xsd:int\"/>\n  <xsd:element name=\"i8\" type=\"xsd:long\"/>\n  <xsd:element name=\"int\" type=\"xsd:int\"/>\n  <xsd:element name=\"ui1\" type=\"xsd:unsignedByte\"/>\n  <xsd:element name=\"ui2\" type=\"xsd:unsignedShort\"/>\n  <xsd:element name=\"ui4\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"ui8\" type=\"xsd:unsignedLong\"/>\n  <xsd:element name=\"uint\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"r4\" type=\"xsd:float\"/>\n  <xsd:element name=\"r8\" type=\"xsd:double\"/>\n  <xsd:element name=\"decimal\" type=\"xsd:decimal\"/>\n  <xsd:element name=\"lpstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"lpwstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"bstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"date\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"filetime\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"bool\" type=\"xsd:boolean\"/>\n  <xsd:element name=\"cy\" type=\"ST_Cy\"/>\n  <xsd:element name=\"error\" type=\"ST_Error\"/>\n  <xsd:element name=\"stream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"storage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostorage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"vstream\" type=\"CT_Vstream\"/>\n  <xsd:element name=\"clsid\" type=\"s:ST_Guid\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n  <xsd:simpleType name=\"ST_Integer255\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer255\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer255\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Integer2\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"-2\"/>\n      <xsd:maxInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer2\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer2\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SpacingRule\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SpacingRule\">\n    <xsd:attribute name=\"val\" type=\"ST_SpacingRule\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnSignedInteger\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnSignedInteger\">\n    <xsd:attribute name=\"val\" type=\"ST_UnSignedInteger\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Char\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Char\">\n    <xsd:attribute name=\"val\" type=\"ST_Char\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_XAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_YAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_YAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"centered\"/>\n      <xsd:enumeration value=\"match\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shp\">\n    <xsd:attribute name=\"val\" type=\"ST_Shp\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"skw\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"noBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FType\">\n    <xsd:attribute name=\"val\" type=\"ST_FType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LimLoc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"undOvr\"/>\n      <xsd:enumeration value=\"subSup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LimLoc\">\n    <xsd:attribute name=\"val\" type=\"ST_LimLoc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TopBot\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TopBot\">\n    <xsd:attribute name=\"val\" type=\"ST_TopBot\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Script\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"fraktur\"/>\n      <xsd:enumeration value=\"double-struck\"/>\n      <xsd:enumeration value=\"sans-serif\"/>\n      <xsd:enumeration value=\"monospace\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Script\">\n    <xsd:attribute name=\"val\" type=\"ST_Script\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"i\"/>\n      <xsd:enumeration value=\"bi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualBreak\">\n    <xsd:attribute name=\"alnAt\" type=\"ST_Integer255\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ScriptStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"scr\" minOccurs=\"0\" type=\"CT_Script\"/>\n      <xsd:element name=\"sty\" minOccurs=\"0\" type=\"CT_Style\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPR\">\n    <xsd:sequence>\n      <xsd:element name=\"lit\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n      <xsd:choice>\n        <xsd:element name=\"nor\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n        <xsd:sequence>\n          <xsd:group ref=\"EG_ScriptStyle\"/>\n        </xsd:sequence>\n      </xsd:choice>\n      <xsd:element name=\"brk\" minOccurs=\"0\" type=\"CT_ManualBreak\"/>\n      <xsd:element name=\"aln\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPR\" minOccurs=\"0\"/>\n      <xsd:group ref=\"w:EG_RPr\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:group ref=\"w:EG_RunInnerContent\"/>\n        <xsd:element name=\"t\" type=\"CT_Text\" minOccurs=\"0\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CtrlPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"w:EG_RPrMath\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AccPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Acc\">\n    <xsd:sequence>\n      <xsd:element name=\"accPr\" type=\"CT_AccPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarPr\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar\">\n    <xsd:sequence>\n      <xsd:element name=\"barPr\" type=\"CT_BarPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"opEmu\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBreak\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"diff\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"brk\" type=\"CT_ManualBreak\" minOccurs=\"0\"/>\n      <xsd:element name=\"aln\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Box\">\n    <xsd:sequence>\n      <xsd:element name=\"boxPr\" type=\"CT_BoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"hideTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideBot\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideLeft\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideRight\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeH\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeV\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeBLTR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeTLBR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBox\">\n    <xsd:sequence>\n      <xsd:element name=\"borderBoxPr\" type=\"CT_BorderBoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPr\">\n    <xsd:sequence>\n      <xsd:element name=\"begChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"sepChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"endChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shp\" type=\"CT_Shp\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_D\">\n    <xsd:sequence>\n      <xsd:element name=\"dPr\" type=\"CT_DPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"objDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArr\">\n    <xsd:sequence>\n      <xsd:element name=\"eqArrPr\" type=\"CT_EqArrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FPr\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FType\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:sequence>\n      <xsd:element name=\"fPr\" type=\"CT_FPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"num\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"den\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FuncPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Func\">\n    <xsd:sequence>\n      <xsd:element name=\"funcPr\" type=\"CT_FuncPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"fName\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"vertJc\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChr\">\n    <xsd:sequence>\n      <xsd:element name=\"groupChrPr\" type=\"CT_GroupChrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLowPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLow\">\n    <xsd:sequence>\n      <xsd:element name=\"limLowPr\" type=\"CT_LimLowPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUppPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUpp\">\n    <xsd:sequence>\n      <xsd:element name=\"limUppPr\" type=\"CT_LimUppPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCPr\">\n    <xsd:sequence>\n      <xsd:element name=\"count\" type=\"CT_Integer255\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcJc\" type=\"CT_XAlign\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MC\">\n    <xsd:sequence>\n      <xsd:element name=\"mcPr\" type=\"CT_MCPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCS\">\n    <xsd:sequence>\n      <xsd:element name=\"mc\" type=\"CT_MC\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"plcHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcs\" type=\"CT_MCS\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MR\">\n    <xsd:sequence>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_M\">\n    <xsd:sequence>\n      <xsd:element name=\"mPr\" type=\"CT_MPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"mr\" type=\"CT_MR\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NaryPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"limLoc\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"supHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Nary\">\n    <xsd:sequence>\n      <xsd:element name=\"naryPr\" type=\"CT_NaryPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhantPr\">\n    <xsd:sequence>\n      <xsd:element name=\"show\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroWid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroAsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroDesc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"transp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Phant\">\n    <xsd:sequence>\n      <xsd:element name=\"phantPr\" type=\"CT_PhantPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadPr\">\n    <xsd:sequence>\n      <xsd:element name=\"degHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rad\">\n    <xsd:sequence>\n      <xsd:element name=\"radPr\" type=\"CT_RadPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"deg\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPrePr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPre\">\n    <xsd:sequence>\n      <xsd:element name=\"sPrePr\" type=\"CT_SPrePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSub\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubPr\" type=\"CT_SSubPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"alnScr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubSupPr\" type=\"CT_SSubSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSupPr\" type=\"CT_SSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OMathMathElements\">\n    <xsd:choice>\n      <xsd:element name=\"acc\" type=\"CT_Acc\"/>\n      <xsd:element name=\"bar\" type=\"CT_Bar\"/>\n      <xsd:element name=\"box\" type=\"CT_Box\"/>\n      <xsd:element name=\"borderBox\" type=\"CT_BorderBox\"/>\n      <xsd:element name=\"d\" type=\"CT_D\"/>\n      <xsd:element name=\"eqArr\" type=\"CT_EqArr\"/>\n      <xsd:element name=\"f\" type=\"CT_F\"/>\n      <xsd:element name=\"func\" type=\"CT_Func\"/>\n      <xsd:element name=\"groupChr\" type=\"CT_GroupChr\"/>\n      <xsd:element name=\"limLow\" type=\"CT_LimLow\"/>\n      <xsd:element name=\"limUpp\" type=\"CT_LimUpp\"/>\n      <xsd:element name=\"m\" type=\"CT_M\"/>\n      <xsd:element name=\"nary\" type=\"CT_Nary\"/>\n      <xsd:element name=\"phant\" type=\"CT_Phant\"/>\n      <xsd:element name=\"rad\" type=\"CT_Rad\"/>\n      <xsd:element name=\"sPre\" type=\"CT_SPre\"/>\n      <xsd:element name=\"sSub\" type=\"CT_SSub\"/>\n      <xsd:element name=\"sSubSup\" type=\"CT_SSubSup\"/>\n      <xsd:element name=\"sSup\" type=\"CT_SSup\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_OMathElements\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_OMathMathElements\"/>\n      <xsd:group ref=\"w:EG_PContentMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OMathArgPr\">\n    <xsd:sequence>\n      <xsd:element name=\"argSz\" type=\"CT_Integer2\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathArg\">\n    <xsd:sequence>\n      <xsd:element name=\"argPr\" type=\"CT_OMathArgPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"centerGroup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OMathJc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathParaPr\">\n    <xsd:sequence>\n      <xsd:element name=\"jc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBin\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"before\"/>\n      <xsd:enumeration value=\"after\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBin\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBin\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBinSub\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"--\"/>\n      <xsd:enumeration value=\"-+\"/>\n      <xsd:enumeration value=\"+-\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBinSub\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBinSub\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathPr\">\n    <xsd:sequence>\n      <xsd:element name=\"mathFont\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBin\" type=\"CT_BreakBin\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBinSub\" type=\"CT_BreakBinSub\" minOccurs=\"0\"/>\n      <xsd:element name=\"smallFrac\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dispDef\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"rMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"defJc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"preSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"postSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"interSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"intraSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"wrapIndent\" type=\"CT_TwipsMeasure\"/>\n        <xsd:element name=\"wrapRight\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"intLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"naryLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"mathPr\" type=\"CT_MathPr\"/>\n  <xsd:complexType name=\"CT_OMathPara\">\n    <xsd:sequence>\n      <xsd:element name=\"oMathParaPr\" type=\"CT_OMathParaPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OMath\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMath\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"oMathPara\" type=\"CT_OMathPara\"/>\n  <xsd:element name=\"oMath\" type=\"CT_OMath\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  blockDefault=\"#all\">\n  <xsd:simpleType name=\"ST_RelationshipId\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:attribute name=\"id\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"embed\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"link\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"dm\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"lo\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"qs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"cs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"blip\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"pict\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"href\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topRight\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomRight\" type=\"ST_RelationshipId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import \n    namespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n    schemaLocation=\"dml-spreadsheetDrawing.xsd\"/>\n  <xsd:complexType name=\"CT_AutoFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"filterColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FilterColumn\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FilterColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"filters\" type=\"CT_Filters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top10\" type=\"CT_Top10\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customFilters\" type=\"CT_CustomFilters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dynamicFilter\" type=\"CT_DynamicFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colorFilter\" type=\"CT_ColorFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconFilter\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_IconFilter\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"colId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"hiddenButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showButton\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" type=\"CT_Filter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dateGroupItem\" type=\"CT_DateGroupItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n    <xsd:attribute name=\"blank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calendarType\" type=\"s:ST_CalendarType\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filter\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"customFilter\" type=\"CT_CustomFilter\" minOccurs=\"1\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"and\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilter\">\n    <xsd:attribute name=\"operator\" type=\"ST_FilterOperator\" default=\"equal\" use=\"optional\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Top10\">\n    <xsd:attribute name=\"top\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"filterVal\" type=\"xsd:double\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorFilter\">\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"cellColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconFilter\">\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"required\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FilterOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DynamicFilter\">\n    <xsd:attribute name=\"type\" type=\"ST_DynamicFilterType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"valIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxVal\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DynamicFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n      <xsd:enumeration value=\"belowAverage\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_IconSetType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"3Arrows\"/>\n      <xsd:enumeration value=\"3ArrowsGray\"/>\n      <xsd:enumeration value=\"3Flags\"/>\n      <xsd:enumeration value=\"3TrafficLights1\"/>\n      <xsd:enumeration value=\"3TrafficLights2\"/>\n      <xsd:enumeration value=\"3Signs\"/>\n      <xsd:enumeration value=\"3Symbols\"/>\n      <xsd:enumeration value=\"3Symbols2\"/>\n      <xsd:enumeration value=\"4Arrows\"/>\n      <xsd:enumeration value=\"4ArrowsGray\"/>\n      <xsd:enumeration value=\"4RedToBlack\"/>\n      <xsd:enumeration value=\"4Rating\"/>\n      <xsd:enumeration value=\"4TrafficLights\"/>\n      <xsd:enumeration value=\"5Arrows\"/>\n      <xsd:enumeration value=\"5ArrowsGray\"/>\n      <xsd:enumeration value=\"5Rating\"/>\n      <xsd:enumeration value=\"5Quarters\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SortState\">\n    <xsd:sequence>\n      <xsd:element name=\"sortCondition\" minOccurs=\"0\" maxOccurs=\"64\" type=\"CT_SortCondition\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"columnSort\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"caseSensitive\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortMethod\" type=\"ST_SortMethod\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SortCondition\">\n    <xsd:attribute name=\"descending\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortBy\" type=\"ST_SortBy\" use=\"optional\" default=\"value\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"customList\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3Arrows\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cellColor\"/>\n      <xsd:enumeration value=\"fontColor\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SortMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stroke\"/>\n      <xsd:enumeration value=\"pinYin\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DateGroupItem\">\n    <xsd:attribute name=\"year\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"month\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"day\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"hour\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"minute\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"second\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"dateTimeGrouping\" type=\"ST_DateTimeGrouping\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTimeGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"year\"/>\n      <xsd:enumeration value=\"month\"/>\n      <xsd:enumeration value=\"day\"/>\n      <xsd:enumeration value=\"hour\"/>\n      <xsd:enumeration value=\"minute\"/>\n      <xsd:enumeration value=\"second\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellRef\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ref\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefA\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Sqref\">\n    <xsd:list itemType=\"ST_Ref\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Formula\">\n    <xsd:restriction base=\"s:ST_Xstring\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedIntHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedShortHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XStringElement\">\n    <xsd:attribute name=\"v\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectAnchor\">\n    <xsd:sequence>\n      <xsd:element ref=\"xdr:from\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"xdr:to\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"moveWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sizeWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"calcChain\" type=\"CT_CalcChain\"/>\n  <xsd:complexType name=\"CT_CalcChain\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_CalcCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcCell\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"l\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"a\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"authors\" type=\"CT_Authors\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentList\" type=\"CT_CommentList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Authors\">\n    <xsd:sequence>\n      <xsd:element name=\"author\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"text\" type=\"CT_Rst\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentPr\" type=\"CT_CommentPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"textHAlign\" type=\"ST_TextHAlign\" use=\"optional\" default=\"left\"/>\n    <xsd:attribute name=\"textVAlign\" type=\"ST_TextVAlign\" use=\"optional\" default=\"top\"/>\n    <xsd:attribute name=\"lockText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"justLastX\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextHAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"MapInfo\" type=\"CT_MapInfo\"/>\n  <xsd:complexType name=\"CT_MapInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"Schema\" type=\"CT_Schema\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Map\" type=\"CT_Map\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectionNamespaces\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Schema\" mixed=\"true\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaRef\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"Namespace\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"SchemaLanguage\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Map\">\n    <xsd:sequence>\n      <xsd:element name=\"DataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"Name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"RootElement\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"ShowImportExportValidationErrors\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"AutoFit\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"Append\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveSortAFLayout\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveFormat\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"DataBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBinding\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"ConnectionID\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DataBindingLoadMode\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"connections\" type=\"CT_Connections\"/>\n  <xsd:complexType name=\"CT_Connections\">\n    <xsd:sequence>\n      <xsd:element name=\"connection\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Connection\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:sequence>\n      <xsd:element name=\"dbPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DbPr\"/>\n      <xsd:element name=\"olapPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_OlapPr\"/>\n      <xsd:element name=\"webPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_WebPr\"/>\n      <xsd:element name=\"textPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextPr\"/>\n      <xsd:element name=\"parameters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Parameters\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"odcFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"keepAlive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"interval\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"reconnectionMethod\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"refreshedVersion\" use=\"required\" type=\"xsd:unsignedByte\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" use=\"optional\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"savePassword\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"new\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"deleted\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"onlyUseConnectionFile\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"background\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"credentials\" use=\"optional\" type=\"ST_CredMethod\" default=\"integrated\"/>\n    <xsd:attribute name=\"singleSignOnId\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CredMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"integrated\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"stored\"/>\n      <xsd:enumeration value=\"prompt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DbPr\">\n    <xsd:attribute name=\"connection\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"command\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"serverCommand\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"commandType\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OlapPr\">\n    <xsd:attribute name=\"local\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"localConnection\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"localRefresh\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sendLocale\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowDrillCount\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"serverFill\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverNumberFormat\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFont\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFontColor\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tables\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Tables\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"xml\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sourceData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parsePre\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl97\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"textDates\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl2000\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"url\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"post\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"htmlTables\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"htmlFormat\" use=\"optional\" type=\"ST_HtmlFmt\" default=\"none\"/>\n    <xsd:attribute name=\"editPage\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HtmlFmt\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rtf\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Parameters\">\n    <xsd:sequence>\n      <xsd:element name=\"parameter\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Parameter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sqlType\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"parameterType\" use=\"optional\" type=\"ST_ParameterType\" default=\"prompt\"/>\n    <xsd:attribute name=\"refreshOnChange\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"boolean\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"double\" use=\"optional\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"integer\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"string\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cell\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ParameterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"prompt\"/>\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Tables\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_TableMissing\"/>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableMissing\"/>\n  <xsd:complexType name=\"CT_TextPr\">\n    <xsd:sequence>\n      <xsd:element name=\"textFields\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextFields\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fileType\" use=\"optional\" type=\"ST_FileType\" default=\"win\"/>\n    <xsd:attribute name=\"codePage\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1252\"/>\n    <xsd:attribute name=\"characterSet\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\" default=\"\"/>\n    <xsd:attribute name=\"delimited\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"decimal\" use=\"optional\" type=\"s:ST_Xstring\" default=\".\"/>\n    <xsd:attribute name=\"thousands\" use=\"optional\" type=\"s:ST_Xstring\" default=\",\"/>\n    <xsd:attribute name=\"tab\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"space\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"comma\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"semicolon\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"qualifier\" use=\"optional\" type=\"ST_Qualifier\" default=\"doubleQuote\"/>\n    <xsd:attribute name=\"delimiter\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FileType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"mac\"/>\n      <xsd:enumeration value=\"win\"/>\n      <xsd:enumeration value=\"dos\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"other\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Qualifier\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doubleQuote\"/>\n      <xsd:enumeration value=\"singleQuote\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextFields\">\n    <xsd:sequence>\n      <xsd:element name=\"textField\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_TextField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"ST_ExternalConnectionType\" default=\"general\"/>\n    <xsd:attribute name=\"position\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ExternalConnectionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"MDY\"/>\n      <xsd:enumeration value=\"DMY\"/>\n      <xsd:enumeration value=\"YMD\"/>\n      <xsd:enumeration value=\"MYD\"/>\n      <xsd:enumeration value=\"DYM\"/>\n      <xsd:enumeration value=\"YDM\"/>\n      <xsd:enumeration value=\"skip\"/>\n      <xsd:enumeration value=\"EMD\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"pivotCacheDefinition\" type=\"CT_PivotCacheDefinition\"/>\n  <xsd:element name=\"pivotCacheRecords\" type=\"CT_PivotCacheRecords\"/>\n  <xsd:element name=\"pivotTableDefinition\" type=\"CT_pivotTableDefinition\"/>\n  <xsd:complexType name=\"CT_PivotCacheDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheSource\" type=\"CT_CacheSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheFields\" type=\"CT_CacheFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheHierarchies\" minOccurs=\"0\" type=\"CT_CacheHierarchies\"/>\n      <xsd:element name=\"kpis\" minOccurs=\"0\" type=\"CT_PCDKPIs\"/>\n      <xsd:element name=\"tupleCache\" minOccurs=\"0\" type=\"CT_TupleCache\"/>\n      <xsd:element name=\"calculatedItems\" minOccurs=\"0\" type=\"CT_CalculatedItems\"/>\n      <xsd:element name=\"calculatedMembers\" type=\"CT_CalculatedMembers\" minOccurs=\"0\"/>\n      <xsd:element name=\"dimensions\" type=\"CT_Dimensions\" minOccurs=\"0\"/>\n      <xsd:element name=\"measureGroups\" type=\"CT_MeasureGroups\" minOccurs=\"0\"/>\n      <xsd:element name=\"maps\" type=\"CT_MeasureDimensionMaps\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalid\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"optimizeMemory\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshedBy\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDate\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDateIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"backgroundQuery\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingItemsLimit\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"refreshedVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"recordCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"upgradeOnRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tupleCache\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportSubquery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportAdvancedDrill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheFields\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheField\" type=\"CT_CacheField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheField\">\n    <xsd:sequence>\n      <xsd:element name=\"sharedItems\" type=\"CT_SharedItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fieldGroup\" minOccurs=\"0\" type=\"CT_FieldGroup\"/>\n      <xsd:element name=\"mpMap\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"propertyName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueList\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqlType\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"databaseField\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"mappingCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"memberPropertyField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheSource\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"worksheetSource\" type=\"CT_WorksheetSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"consolidation\" type=\"CT_Consolidation\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_SourceType\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" default=\"0\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"external\"/>\n      <xsd:enumeration value=\"consolidation\"/>\n      <xsd:enumeration value=\"scenario\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorksheetSource\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Consolidation\">\n    <xsd:sequence>\n      <xsd:element name=\"pages\" type=\"CT_Pages\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rangeSets\" type=\"CT_RangeSets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"autoPage\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pages\">\n    <xsd:sequence>\n      <xsd:element name=\"page\" type=\"CT_PCDSCPage\" minOccurs=\"1\" maxOccurs=\"4\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSCPage\">\n    <xsd:sequence>\n      <xsd:element name=\"pageItem\" type=\"CT_PageItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSets\">\n    <xsd:sequence>\n      <xsd:element name=\"rangeSet\" type=\"CT_RangeSet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSet\">\n    <xsd:attribute name=\"i1\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i2\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i3\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i4\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedItems\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"s\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"containsSemiMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsNonDate\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsDate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsString\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsInteger\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"minDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"longText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Missing\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Number\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Error\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateTime\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"rangePr\" minOccurs=\"0\" type=\"CT_RangePr\"/>\n      <xsd:element name=\"discretePr\" minOccurs=\"0\" type=\"CT_DiscretePr\"/>\n      <xsd:element name=\"groupItems\" minOccurs=\"0\" type=\"CT_GroupItems\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"par\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"base\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangePr\">\n    <xsd:attribute name=\"autoStart\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"autoEnd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"groupBy\" type=\"ST_GroupBy\" default=\"range\"/>\n    <xsd:attribute name=\"startNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"endNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"startDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"endDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"groupInterval\" type=\"xsd:double\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GroupBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"seconds\"/>\n      <xsd:enumeration value=\"minutes\"/>\n      <xsd:enumeration value=\"hours\"/>\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"quarters\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DiscretePr\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupItems\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCacheRecords\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Record\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Record\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPIs\">\n    <xsd:sequence>\n      <xsd:element name=\"kpi\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PCDKPI\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPI\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"value\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"goal\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"status\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"trend\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"weight\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"time\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheHierarchy\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CacheHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldsUsage\" minOccurs=\"0\" type=\"CT_FieldsUsage\"/>\n      <xsd:element name=\"groupLevels\" minOccurs=\"0\" type=\"CT_GroupLevels\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parentSet\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"attribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"keyAttribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultMemberUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"dimensionUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measures\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"oneField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"memberValueDatatype\" use=\"optional\" type=\"xsd:unsignedShort\"/>\n    <xsd:attribute name=\"unbalanced\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"unbalancedGroup\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldsUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldUsage\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FieldUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldUsage\">\n    <xsd:attribute name=\"x\" use=\"required\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevels\">\n    <xsd:sequence>\n      <xsd:element name=\"groupLevel\" maxOccurs=\"unbounded\" type=\"CT_GroupLevel\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevel\">\n    <xsd:sequence>\n      <xsd:element name=\"groups\" minOccurs=\"0\" type=\"CT_Groups\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"user\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customRollUp\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Groups\">\n    <xsd:sequence>\n      <xsd:element name=\"group\" maxOccurs=\"unbounded\" type=\"CT_LevelGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMembers\" type=\"CT_GroupMembers\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueParent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMember\" maxOccurs=\"unbounded\" type=\"CT_GroupMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMember\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"group\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TupleCache\">\n    <xsd:sequence>\n      <xsd:element name=\"entries\" minOccurs=\"0\" type=\"CT_PCDSDTCEntries\"/>\n      <xsd:element name=\"sets\" minOccurs=\"0\" type=\"CT_Sets\"/>\n      <xsd:element name=\"queryCache\" minOccurs=\"0\" type=\"CT_QueryCache\"/>\n      <xsd:element name=\"serverFormats\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ServerFormats\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormat\">\n    <xsd:attribute name=\"culture\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"format\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"serverFormat\" type=\"CT_ServerFormat\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSDTCEntries\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuples\">\n    <xsd:sequence>\n      <xsd:element name=\"tpl\" type=\"CT_Tuple\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuple\">\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"item\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sets\">\n    <xsd:sequence>\n      <xsd:element name=\"set\" maxOccurs=\"unbounded\" type=\"CT_Set\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Set\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"sortByTuple\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"maxRank\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"setDefinition\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_SortType\" default=\"none\"/>\n    <xsd:attribute name=\"queryFailed\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n      <xsd:enumeration value=\"ascendingAlpha\"/>\n      <xsd:enumeration value=\"descendingAlpha\"/>\n      <xsd:enumeration value=\"ascendingNatural\"/>\n      <xsd:enumeration value=\"descendingNatural\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_QueryCache\">\n    <xsd:sequence>\n      <xsd:element name=\"query\" maxOccurs=\"unbounded\" type=\"CT_Query\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Query\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItems\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedItem\" maxOccurs=\"unbounded\" type=\"CT_CalculatedItem\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItem\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedMember\" maxOccurs=\"unbounded\" type=\"CT_CalculatedMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMember\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"memberName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"solveOrder\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_pivotTableDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"location\" type=\"CT_Location\"/>\n      <xsd:element name=\"pivotFields\" type=\"CT_PivotFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowFields\" type=\"CT_RowFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowItems\" type=\"CT_rowItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"colFields\" type=\"CT_ColFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"colItems\" type=\"CT_colItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageFields\" type=\"CT_PageFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataFields\" type=\"CT_DataFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"formats\" type=\"CT_Formats\" minOccurs=\"0\"/>\n      <xsd:element name=\"conditionalFormats\" type=\"CT_ConditionalFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"chartFormats\" type=\"CT_ChartFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotHierarchies\" type=\"CT_PivotHierarchies\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotTableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotTableStyle\"/>\n      <xsd:element name=\"filters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotFilters\"/>\n      <xsd:element name=\"rowHierarchiesUsage\" type=\"CT_RowHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"colHierarchiesUsage\" type=\"CT_ColHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cacheId\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dataOnRows\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dataPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"dataCaption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"grandTotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"errorCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showError\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showMissing\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"pageStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"pivotTableStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"vacatedStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"tag\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"updatedVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"asteriskTotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showItems\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"editData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"disableFieldList\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showCalcMbrs\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"visualTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showMultipleLabel\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataDropDown\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"printDrill\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showMemberPropertyTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableWizard\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableFieldProperties\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"useAutoFormatting\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"pageWrap\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"pageOverThenDown\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalHiddenItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"colGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fieldPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mergeItem\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showDropZones\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"showEmptyRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showEmptyCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showHeaders\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outlineData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"compactData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"gridDropZones\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"immersive\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleFieldFilters\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"chartFormat\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"rowHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"colHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fieldListSortAscending\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mdxSubqueries\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customListSort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Location\">\n    <xsd:attribute name=\"ref\" use=\"required\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"firstHeaderRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataCol\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"rowPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"colPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotField\" maxOccurs=\"unbounded\" type=\"CT_PivotField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotField\">\n    <xsd:sequence>\n      <xsd:element name=\"items\" minOccurs=\"0\" type=\"CT_Items\"/>\n      <xsd:element name=\"autoSortScope\" minOccurs=\"0\" type=\"CT_AutoSortScope\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"axis\" use=\"optional\" type=\"ST_Axis\"/>\n    <xsd:attribute name=\"dataField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showDropDowns\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hiddenLevel\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueMemberProperty\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"allDrilled\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showAll\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"insertBlankRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"insertPageBreak\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"autoShow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"topAutoShow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hideNewItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"measureFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPageCount\" type=\"xsd:unsignedInt\" default=\"10\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_FieldSortType\" default=\"manual\"/>\n    <xsd:attribute name=\"dataSourceSort\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nonAutoSortDefault\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rankBy\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showPropCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultAttributeDrillState\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoSortScope\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Items\">\n    <xsd:sequence>\n      <xsd:element name=\"item\" maxOccurs=\"unbounded\" type=\"CT_Item\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Item\">\n    <xsd:attribute name=\"n\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"h\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"m\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"e\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pageField\" maxOccurs=\"unbounded\" type=\"CT_PageField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"item\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cap\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataFields\">\n    <xsd:sequence>\n      <xsd:element name=\"dataField\" maxOccurs=\"unbounded\" type=\"CT_DataField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataField\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"subtotal\" type=\"ST_DataConsolidateFunction\" default=\"sum\"/>\n    <xsd:attribute name=\"showDataAs\" type=\"ST_ShowDataAs\" default=\"normal\"/>\n    <xsd:attribute name=\"baseField\" type=\"xsd:int\" default=\"-1\"/>\n    <xsd:attribute name=\"baseItem\" type=\"xsd:unsignedInt\" default=\"1048832\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_rowItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_colItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_I\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_X\">\n    <xsd:attribute name=\"v\" type=\"xsd:int\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Field\">\n    <xsd:attribute name=\"x\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formats\">\n    <xsd:sequence>\n      <xsd:element name=\"format\" maxOccurs=\"unbounded\" type=\"CT_Format\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Format\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"action\" type=\"ST_FormatAction\" default=\"formatting\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"conditionalFormat\" maxOccurs=\"unbounded\" type=\"CT_ConditionalFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotAreas\" type=\"CT_PivotAreas\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"scope\" type=\"ST_Scope\" default=\"selection\"/>\n    <xsd:attribute name=\"type\" type=\"ST_Type\" default=\"none\"/>\n    <xsd:attribute name=\"priority\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreas\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Scope\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"selection\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"field\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Type\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"column\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChartFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"chartFormat\" maxOccurs=\"unbounded\" type=\"CT_ChartFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"chart\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"format\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"series\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotHierarchy\" maxOccurs=\"unbounded\" type=\"CT_PivotHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"mps\" minOccurs=\"0\" type=\"CT_MemberProperties\"/>\n      <xsd:element name=\"members\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Members\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showInFieldList\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"rowHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"colHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierarchyUsage\">\n    <xsd:attribute name=\"hierarchyUsage\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"mp\" maxOccurs=\"unbounded\" type=\"CT_MemberProperty\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nameLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pPos\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"field\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Members\">\n    <xsd:sequence>\n      <xsd:element name=\"member\" maxOccurs=\"unbounded\" type=\"CT_Member\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"level\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Member\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dimensions\">\n    <xsd:sequence>\n      <xsd:element name=\"dimension\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotDimension\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotDimension\">\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroups\">\n    <xsd:sequence>\n      <xsd:element name=\"measureGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMaps\">\n    <xsd:sequence>\n      <xsd:element name=\"map\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureDimensionMap\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroup\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMap\">\n    <xsd:attribute name=\"measureGroup\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dimension\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotTableStyle\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"showRowHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotFilter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_AutoFilter\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"mpFld\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" use=\"required\" type=\"ST_PivotFilterType\"/>\n    <xsd:attribute name=\"evalOrder\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureHier\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureFld\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue1\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue2\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShowDataAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"difference\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"percentDiff\"/>\n      <xsd:enumeration value=\"runTotal\"/>\n      <xsd:enumeration value=\"percentOfRow\"/>\n      <xsd:enumeration value=\"percentOfCol\"/>\n      <xsd:enumeration value=\"percentOfTotal\"/>\n      <xsd:enumeration value=\"index\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ItemType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"countA\"/>\n      <xsd:enumeration value=\"avg\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevP\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varP\"/>\n      <xsd:enumeration value=\"grand\"/>\n      <xsd:enumeration value=\"blank\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormatAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"formatting\"/>\n      <xsd:enumeration value=\"drill\"/>\n      <xsd:enumeration value=\"formula\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FieldSortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PivotFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"unknown\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"captionEqual\"/>\n      <xsd:enumeration value=\"captionNotEqual\"/>\n      <xsd:enumeration value=\"captionBeginsWith\"/>\n      <xsd:enumeration value=\"captionNotBeginsWith\"/>\n      <xsd:enumeration value=\"captionEndsWith\"/>\n      <xsd:enumeration value=\"captionNotEndsWith\"/>\n      <xsd:enumeration value=\"captionContains\"/>\n      <xsd:enumeration value=\"captionNotContains\"/>\n      <xsd:enumeration value=\"captionGreaterThan\"/>\n      <xsd:enumeration value=\"captionGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"captionLessThan\"/>\n      <xsd:enumeration value=\"captionLessThanOrEqual\"/>\n      <xsd:enumeration value=\"captionBetween\"/>\n      <xsd:enumeration value=\"captionNotBetween\"/>\n      <xsd:enumeration value=\"valueEqual\"/>\n      <xsd:enumeration value=\"valueNotEqual\"/>\n      <xsd:enumeration value=\"valueGreaterThan\"/>\n      <xsd:enumeration value=\"valueGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"valueLessThan\"/>\n      <xsd:enumeration value=\"valueLessThanOrEqual\"/>\n      <xsd:enumeration value=\"valueBetween\"/>\n      <xsd:enumeration value=\"valueNotBetween\"/>\n      <xsd:enumeration value=\"dateEqual\"/>\n      <xsd:enumeration value=\"dateNotEqual\"/>\n      <xsd:enumeration value=\"dateOlderThan\"/>\n      <xsd:enumeration value=\"dateOlderThanOrEqual\"/>\n      <xsd:enumeration value=\"dateNewerThan\"/>\n      <xsd:enumeration value=\"dateNewerThanOrEqual\"/>\n      <xsd:enumeration value=\"dateBetween\"/>\n      <xsd:enumeration value=\"dateNotBetween\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"references\" minOccurs=\"0\" type=\"CT_PivotAreaReferences\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PivotAreaType\" default=\"normal\"/>\n    <xsd:attribute name=\"dataOnly\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"labelOnly\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"cacheIndex\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"offset\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"collapsedLevelsAreSubtotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PivotAreaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"origin\"/>\n      <xsd:enumeration value=\"button\"/>\n      <xsd:enumeration value=\"topEnd\"/>\n      <xsd:enumeration value=\"topRight\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotAreaReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"reference\" maxOccurs=\"unbounded\" type=\"CT_PivotAreaReference\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreaReference\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"selected\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"byPosition\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"relative\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Index\">\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Axis\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"axisRow\"/>\n      <xsd:enumeration value=\"axisCol\"/>\n      <xsd:enumeration value=\"axisPage\"/>\n      <xsd:enumeration value=\"axisValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"queryTable\" type=\"CT_QueryTable\"/>\n  <xsd:complexType name=\"CT_QueryTable\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableRefresh\" type=\"CT_QueryTableRefresh\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"headers\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"backgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"firstBackgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"growShrinkType\" type=\"ST_GrowShrinkType\" use=\"optional\"\n      default=\"insertDelete\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removeDataOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"adjustColumnWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"intermediate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableRefresh\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableFields\" type=\"CT_QueryTableFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"queryTableDeletedFields\" type=\"CT_QueryTableDeletedFields\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserveSortFilterLayout\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fieldIdWrapped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headersInLastRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"minimumVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"nextId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"unboundColumnsLeft\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"unboundColumnsRight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableDeletedFields\">\n    <xsd:sequence>\n      <xsd:element name=\"deletedField\" type=\"CT_DeletedField\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DeletedField\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableFields\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableField\" type=\"CT_QueryTableField\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataBound\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clipped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tableColumnId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GrowShrinkType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertDelete\"/>\n      <xsd:enumeration value=\"insertClear\"/>\n      <xsd:enumeration value=\"overwriteClear\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"sst\" type=\"CT_Sst\"/>\n  <xsd:complexType name=\"CT_Sst\">\n    <xsd:sequence>\n      <xsd:element name=\"si\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"uniqueCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhoneticType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"halfwidthKatakana\"/>\n      <xsd:enumeration value=\"fullwidthKatakana\"/>\n      <xsd:enumeration value=\"Hiragana\"/>\n      <xsd:enumeration value=\"noConversion\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhoneticAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhoneticRun\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RElt\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPrElt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrElt\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rFont\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rst\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"r\" type=\"CT_RElt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPh\" type=\"CT_PhoneticRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"phoneticPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PhoneticPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhoneticPr\">\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PhoneticType\" use=\"optional\" default=\"fullwidthKatakana\"/>\n    <xsd:attribute name=\"alignment\" type=\"ST_PhoneticAlignment\" use=\"optional\" default=\"left\"/>\n  </xsd:complexType>\n  <xsd:element name=\"headers\" type=\"CT_RevisionHeaders\"/>\n  <xsd:element name=\"revisions\" type=\"CT_Revisions\"/>\n  <xsd:complexType name=\"CT_RevisionHeaders\">\n    <xsd:sequence>\n      <xsd:element name=\"header\" type=\"CT_RevisionHeader\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"lastGuid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shared\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"diskRevisions\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"trackRevisions\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"exclusive\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"revisionId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"version\" type=\"xsd:int\" default=\"1\"/>\n    <xsd:attribute name=\"keepChangeHistory\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"protected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveHistory\" type=\"xsd:unsignedInt\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Revisions\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rrc\" type=\"CT_RevisionRowColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rm\" type=\"CT_RevisionMove\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcv\" type=\"CT_RevisionCustomView\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rsnm\" type=\"CT_RevisionSheetRename\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ris\" type=\"CT_RevisionInsertSheet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"raf\" type=\"CT_RevisionAutoFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rdn\" type=\"CT_RevisionDefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcmt\" type=\"CT_RevisionComment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rqt\" type=\"CT_RevisionQueryTableField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcft\" type=\"CT_RevisionConflict\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_RevData\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ua\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ra\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_RevisionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetIdMap\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_SheetIdMap\"/>\n      <xsd:element name=\"reviewedList\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ReviewedRevisions\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"maxSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"minRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"maxRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetIdMap\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetId\" type=\"CT_SheetId\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetId\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReviewedRevisions\">\n    <xsd:sequence>\n      <xsd:element name=\"reviewed\" type=\"CT_Reviewed\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Reviewed\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UndoInfo\">\n    <xsd:attribute name=\"index\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"exp\" type=\"ST_FormulaExpression\" use=\"required\"/>\n    <xsd:attribute name=\"ref3D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"array\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cs\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dr\" type=\"ST_RefA\" use=\"required\"/>\n    <xsd:attribute name=\"dn\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionRowColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_rwColActionType\" use=\"required\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionMove\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"source\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"destination\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"sourceSheetId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCustomView\">\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionSheetRename\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"oldName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"newName\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionInsertSheet\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetPosition\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCellChange\">\n    <xsd:sequence>\n      <xsd:element name=\"oc\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nc\" type=\"CT_Cell\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"odxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ndxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"odxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldQuotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"oldPh\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"endOfListFormulaUpdate\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionAutoFormatting\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionComment\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"cell\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" default=\"add\"/>\n    <xsd:attribute name=\"alwaysShow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"author\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"oldLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"newLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionDefinedName\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oldFormula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"customView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldFunction\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldFunctionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"shortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldShortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldHidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldCustomMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldDescription\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldHelp\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldStatusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldComment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionConflict\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionQueryTableField\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"fieldId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_rwColActionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertRow\"/>\n      <xsd:enumeration value=\"deleteRow\"/>\n      <xsd:enumeration value=\"insertCol\"/>\n      <xsd:enumeration value=\"deleteCol\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RevisionAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"add\"/>\n      <xsd:enumeration value=\"delete\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormulaExpression\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ref\"/>\n      <xsd:enumeration value=\"refError\"/>\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"areaError\"/>\n      <xsd:enumeration value=\"computedArea\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"users\" type=\"CT_Users\"/>\n  <xsd:complexType name=\"CT_Users\">\n    <xsd:sequence>\n      <xsd:element name=\"userInfo\" minOccurs=\"0\" maxOccurs=\"256\" type=\"CT_SharedUser\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedUser\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"worksheet\" type=\"CT_Worksheet\"/>\n  <xsd:element name=\"chartsheet\" type=\"CT_Chartsheet\"/>\n  <xsd:element name=\"dialogsheet\" type=\"CT_Dialogsheet\"/>\n  <xsd:complexType name=\"CT_Macrosheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dialogsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" minOccurs=\"0\" type=\"CT_SheetPr\"/>\n      <xsd:element name=\"sheetViews\" minOccurs=\"0\" type=\"CT_SheetViews\"/>\n      <xsd:element name=\"sheetFormatPr\" minOccurs=\"0\" type=\"CT_SheetFormatPr\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" minOccurs=\"0\" type=\"CT_CustomSheetViews\"/>\n      <xsd:element name=\"printOptions\" minOccurs=\"0\" type=\"CT_PrintOptions\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" minOccurs=\"0\" type=\"CT_PageSetup\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" minOccurs=\"0\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"legacyDrawing\" minOccurs=\"0\" type=\"CT_LegacyDrawing\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Worksheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetCalcPr\" type=\"CT_SheetCalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protectedRanges\" type=\"CT_ProtectedRanges\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scenarios\" type=\"CT_Scenarios\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mergeCells\" type=\"CT_MergeCells\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dataValidations\" type=\"CT_DataValidations\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hyperlinks\" type=\"CT_Hyperlinks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellWatches\" type=\"CT_CellWatches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ignoredErrors\" type=\"CT_IgnoredErrors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableParts\" type=\"CT_TableParts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetCalcPr\">\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetFormatPr\">\n    <xsd:attribute name=\"baseColWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"8\"/>\n    <xsd:attribute name=\"defaultColWidth\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultRowHeight\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zeroHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevelRow\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"outlineLevelCol\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cols\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"CT_Col\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Col\">\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bestFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"phonetic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellSpan\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellSpans\">\n    <xsd:list itemType=\"ST_CellSpan\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spans\" type=\"ST_CellSpans\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"customFormat\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ht\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cell\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_CellFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"is\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"cm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"inlineStr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellFormulaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"array\"/>\n      <xsd:enumeration value=\"dataTable\"/>\n      <xsd:enumeration value=\"shared\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlinePr\" type=\"CT_OutlinePr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetUpPr\" type=\"CT_PageSetUpPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"syncHorizontal\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncVertical\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"transitionEvaluation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"transitionEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filterMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableFormatConditionsCalculation\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetDimension\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_SheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"pivotSelection\" type=\"CT_PivotSelection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"windowProtection\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowColHeaders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showZeros\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rightToLeft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultGridColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showWhiteSpace\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" use=\"optional\" default=\"normal\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"64\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"zoomScaleNormal\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScaleSheetLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScalePageLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pane\">\n    <xsd:attribute name=\"xSplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ySplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activePane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"state\" type=\"ST_PaneState\" use=\"optional\" default=\"split\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSelection\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"showHeader\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"label\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"extendable\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"dimension\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"click\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Selection\">\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"activeCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activeCellId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\" default=\"A1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bottomRight\"/>\n      <xsd:enumeration value=\"topRight\"/>\n      <xsd:enumeration value=\"bottomLeft\"/>\n      <xsd:enumeration value=\"topLeft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"brk\" type=\"CT_Break\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"manualBreakCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Break\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"man\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetViewType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"pageBreakPreview\"/>\n      <xsd:enumeration value=\"pageLayout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OutlinePr\">\n    <xsd:attribute name=\"applyStyles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"summaryBelow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"summaryRight\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetUpPr\">\n    <xsd:attribute name=\"autoPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataConsolidate\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRefs\" type=\"CT_DataRefs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"function\" type=\"ST_DataConsolidateFunction\" use=\"optional\" default=\"sum\"/>\n    <xsd:attribute name=\"startLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"leftLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"topLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"link\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataConsolidateFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevp\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varp\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DataRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRef\" type=\"CT_DataRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataRef\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCells\">\n    <xsd:sequence>\n      <xsd:element name=\"mergeCell\" type=\"CT_MergeCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCell\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTags\" type=\"CT_CellSmartTags\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTag\" type=\"CT_CellSmartTag\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTag\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTagPr\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CellSmartTagPr\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlBased\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTagPr\">\n    <xsd:attribute name=\"key\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LegacyDrawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DrawingHF\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"lho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"che\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"chf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomSheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" default=\"64\"/>\n    <xsd:attribute name=\"showPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"outlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"zeroValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"printArea\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAutoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"filterUnique\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" default=\"normal\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidations\">\n    <xsd:sequence>\n      <xsd:element name=\"dataValidation\" type=\"CT_DataValidation\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"disablePrompts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidation\">\n    <xsd:sequence>\n      <xsd:element name=\"formula1\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formula2\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_DataValidationType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"errorStyle\" type=\"ST_DataValidationErrorStyle\" use=\"optional\"\n      default=\"stop\"/>\n    <xsd:attribute name=\"imeMode\" type=\"ST_DataValidationImeMode\" use=\"optional\" default=\"noControl\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_DataValidationOperator\" use=\"optional\" default=\"between\"/>\n    <xsd:attribute name=\"allowBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showDropDown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInputMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showErrorMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errorTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"error\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"promptTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"prompt\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataValidationType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"list\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"time\"/>\n      <xsd:enumeration value=\"textLength\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationErrorStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stop\"/>\n      <xsd:enumeration value=\"warning\"/>\n      <xsd:enumeration value=\"information\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationImeMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"disabled\"/>\n      <xsd:enumeration value=\"hiragana\"/>\n      <xsd:enumeration value=\"fullKatakana\"/>\n      <xsd:enumeration value=\"halfKatakana\"/>\n      <xsd:enumeration value=\"fullAlpha\"/>\n      <xsd:enumeration value=\"halfAlpha\"/>\n      <xsd:enumeration value=\"fullHangul\"/>\n      <xsd:enumeration value=\"halfHangul\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"expression\"/>\n      <xsd:enumeration value=\"cellIs\"/>\n      <xsd:enumeration value=\"colorScale\"/>\n      <xsd:enumeration value=\"dataBar\"/>\n      <xsd:enumeration value=\"iconSet\"/>\n      <xsd:enumeration value=\"top10\"/>\n      <xsd:enumeration value=\"uniqueValues\"/>\n      <xsd:enumeration value=\"duplicateValues\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContainsText\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n      <xsd:enumeration value=\"containsBlanks\"/>\n      <xsd:enumeration value=\"notContainsBlanks\"/>\n      <xsd:enumeration value=\"containsErrors\"/>\n      <xsd:enumeration value=\"notContainsErrors\"/>\n      <xsd:enumeration value=\"timePeriod\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TimePeriod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"last7Days\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConditionalFormattingOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContains\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfvoType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"formula\"/>\n      <xsd:enumeration value=\"percentile\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ConditionalFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"cfRule\" type=\"CT_CfRule\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CfRule\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"3\"/>\n      <xsd:element name=\"colorScale\" type=\"CT_ColorScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataBar\" type=\"CT_DataBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconSet\" type=\"CT_IconSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfType\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"priority\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"stopIfTrue\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"aboveAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_ConditionalFormattingOperator\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"timePeriod\" type=\"ST_TimePeriod\" use=\"optional\"/>\n    <xsd:attribute name=\"rank\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"stdDev\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"equalAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlinks\">\n    <xsd:sequence>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"location\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"t\" type=\"ST_CellFormulaType\" use=\"optional\" default=\"normal\"/>\n        <xsd:attribute name=\"aca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n        <xsd:attribute name=\"dt2D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"dtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del1\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del2\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"r1\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"r2\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"ca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"bx\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorScale\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBar\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"minLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"10\"/>\n    <xsd:attribute name=\"maxLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"90\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconSet\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3TrafficLights1\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"reverse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cfvo\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfvoType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"gte\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintOptions\">\n    <xsd:attribute name=\"horizontalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"verticalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headings\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLinesSet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToHeight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"pageOrder\" type=\"ST_PageOrder\" use=\"optional\" default=\"downThenOver\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellComments\" type=\"ST_CellComments\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errors\" type=\"ST_PrintError\" use=\"optional\" default=\"displayed\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"downThenOver\"/>\n      <xsd:enumeration value=\"overThenDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellComments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"asDisplayed\"/>\n      <xsd:enumeration value=\"atEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"scaleWithDoc\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintError\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"displayed\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"NA\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Scenarios\">\n    <xsd:sequence>\n      <xsd:element name=\"scenario\" type=\"CT_Scenario\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"current\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scenarios\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formatCells\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertHyperlinks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectLockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"pivotTables\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectUnlockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRanges\">\n    <xsd:sequence>\n      <xsd:element name=\"protectedRange\" type=\"CT_ProtectedRange\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRange\">\n    <xsd:sequence>\n      <xsd:element name=\"securityDescriptor\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"securityDescriptor\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scenario\">\n    <xsd:sequence>\n      <xsd:element name=\"inputCells\" type=\"CT_InputCells\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"user\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InputCells\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"undone\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatches\">\n    <xsd:sequence>\n      <xsd:element name=\"cellWatch\" type=\"CT_CellWatch\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatch\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chartsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_ChartsheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_ChartsheetViews\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_ChartsheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomChartsheetViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_ChartsheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" default=\"100\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"content\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CsPageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomChartsheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"customPr\" type=\"CT_CustomProperty\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"oleObject\" type=\"CT_OleObject\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:element name=\"objectPr\" type=\"CT_ObjectPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dvAspect\" type=\"ST_DvAspect\" use=\"optional\" default=\"DVASPECT_CONTENT\"/>\n    <xsd:attribute name=\"link\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oleUpdate\" type=\"ST_OleUpdate\" use=\"optional\"/>\n    <xsd:attribute name=\"autoLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dde\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DvAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"DVASPECT_CONTENT\"/>\n      <xsd:enumeration value=\"DVASPECT_ICON\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OleUpdate\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"OLEUPDATE_ALWAYS\"/>\n      <xsd:enumeration value=\"OLEUPDATE_ONCALL\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebPublishItems\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishItem\" type=\"CT_WebPublishItem\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishItem\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceType\" type=\"ST_WebSourceType\" use=\"required\"/>\n    <xsd:attribute name=\"sourceRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Controls\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"controlPr\" type=\"CT_ControlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"recalcAlways\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"linkedCell\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"listFillRange\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"cf\" type=\"s:ST_Xstring\" use=\"optional\" default=\"pict\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sheet\"/>\n      <xsd:enumeration value=\"printArea\"/>\n      <xsd:enumeration value=\"autoFilter\"/>\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"pivotTable\"/>\n      <xsd:enumeration value=\"query\"/>\n      <xsd:enumeration value=\"label\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IgnoredErrors\">\n    <xsd:sequence>\n      <xsd:element name=\"ignoredError\" type=\"CT_IgnoredError\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IgnoredError\">\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"evalError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"twoDigitTextYear\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numberStoredAsText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formulaRange\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"unlockedFormula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"emptyCellReference\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"listDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calculatedColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PaneState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"split\"/>\n      <xsd:enumeration value=\"frozen\"/>\n      <xsd:enumeration value=\"frozenSplit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableParts\">\n    <xsd:sequence>\n      <xsd:element name=\"tablePart\" type=\"CT_TablePart\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePart\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"metadata\" type=\"CT_Metadata\"/>\n  <xsd:complexType name=\"CT_Metadata\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataTypes\" type=\"CT_MetadataTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"metadataStrings\" type=\"CT_MetadataStrings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mdxMetadata\" type=\"CT_MdxMetadata\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"futureMetadata\" type=\"CT_FutureMetadata\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"cellMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"valueMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataType\" type=\"CT_MetadataType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataType\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"minSupportedVersion\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ghostRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ghostCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"edit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"delete\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"copy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteValues\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteBorders\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteColWidths\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteNumberFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"merge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitFirst\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"rowColShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearAll\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"clearFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearContents\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"assign\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"coerce\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"adjust\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellMeta\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlocks\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_MetadataBlock\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"rc\" type=\"CT_MetadataRecord\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataRecord\">\n    <xsd:attribute name=\"t\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_FutureMetadataBlock\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"mdx\" type=\"CT_Mdx\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Mdx\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"t\" type=\"CT_MdxTuple\"/>\n      <xsd:element name=\"ms\" type=\"CT_MdxSet\"/>\n      <xsd:element name=\"p\" type=\"CT_MdxMemeberProp\"/>\n      <xsd:element name=\"k\" type=\"CT_MdxKPI\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"f\" type=\"ST_MdxFunctionType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxFunctionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"m\"/>\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"c\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"k\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxTuple\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ct\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"fi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxSet\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ns\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"o\" type=\"ST_MdxSetOrder\" use=\"optional\" default=\"u\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxSetOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"a\"/>\n      <xsd:enumeration value=\"d\"/>\n      <xsd:enumeration value=\"aa\"/>\n      <xsd:enumeration value=\"ad\"/>\n      <xsd:enumeration value=\"na\"/>\n      <xsd:enumeration value=\"nd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxMemeberProp\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxKPI\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"p\" type=\"ST_MdxKPIProperty\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxKPIProperty\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"g\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"m\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MetadataStringIndex\">\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataStrings\">\n    <xsd:sequence>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"singleXmlCells\" type=\"CT_SingleXmlCells\"/>\n  <xsd:complexType name=\"CT_SingleXmlCells\">\n    <xsd:sequence>\n      <xsd:element name=\"singleXmlCell\" type=\"CT_SingleXmlCell\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SingleXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlCellPr\" type=\"CT_XmlCellPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlCellPr\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlPr\" type=\"CT_XmlPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleSheet\" type=\"CT_Stylesheet\"/>\n  <xsd:complexType name=\"CT_Stylesheet\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmts\" type=\"CT_NumFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fonts\" type=\"CT_Fonts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fills\" type=\"CT_Fills\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"borders\" type=\"CT_Borders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyleXfs\" type=\"CT_CellStyleXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellXfs\" type=\"CT_CellXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyles\" type=\"CT_CellStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dxfs\" type=\"CT_Dxfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyles\" type=\"CT_TableStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colors\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellAlignment\">\n    <xsd:attribute name=\"horizontal\" type=\"ST_HorizontalAlignment\" use=\"optional\"/>\n    <xsd:attribute name=\"vertical\" type=\"ST_VerticalAlignment\" default=\"bottom\" use=\"optional\"/>\n    <xsd:attribute name=\"textRotation\" type=\"ST_TextRotation\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapText\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"relativeIndent\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"justifyLastLine\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"shrinkToFit\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"readingOrder\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextRotation\">\n    <xsd:union>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:maxInclusive value=\"180\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:enumeration value=\"255\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:union>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"thin\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hair\"/>\n      <xsd:enumeration value=\"mediumDashed\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"mediumDashDot\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"mediumDashDotDot\"/>\n      <xsd:enumeration value=\"slantDashDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Borders\">\n    <xsd:sequence>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"top\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"diagonal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertical\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"horizontal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"diagonalUp\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"diagonalDown\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderPr\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"style\" type=\"ST_BorderStyle\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellProtection\">\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fills\">\n    <xsd:sequence>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"patternFill\" type=\"CT_PatternFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradientFill\" type=\"CT_GradientFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PatternFill\">\n    <xsd:sequence>\n      <xsd:element name=\"fgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"patternType\" type=\"ST_PatternType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"auto\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indexed\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"theme\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tint\" type=\"xsd:double\" use=\"optional\" default=\"0.0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PatternType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"mediumGray\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"darkHorizontal\"/>\n      <xsd:enumeration value=\"darkVertical\"/>\n      <xsd:enumeration value=\"darkDown\"/>\n      <xsd:enumeration value=\"darkUp\"/>\n      <xsd:enumeration value=\"darkGrid\"/>\n      <xsd:enumeration value=\"darkTrellis\"/>\n      <xsd:enumeration value=\"lightHorizontal\"/>\n      <xsd:enumeration value=\"lightVertical\"/>\n      <xsd:enumeration value=\"lightDown\"/>\n      <xsd:enumeration value=\"lightUp\"/>\n      <xsd:enumeration value=\"lightGrid\"/>\n      <xsd:enumeration value=\"lightTrellis\"/>\n      <xsd:enumeration value=\"gray125\"/>\n      <xsd:enumeration value=\"gray0625\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientFill\">\n    <xsd:sequence>\n      <xsd:element name=\"stop\" type=\"CT_GradientStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_GradientType\" use=\"optional\" default=\"linear\"/>\n    <xsd:attribute name=\"degree\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"position\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GradientType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"path\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"fill\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"centerContinuous\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyleXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Xf\">\n    <xsd:sequence>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"optional\"/>\n    <xsd:attribute name=\"fillId\" type=\"ST_FillId\" use=\"optional\"/>\n    <xsd:attribute name=\"borderId\" type=\"ST_BorderId\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pivotButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"applyNumberFormat\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFont\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFill\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyBorder\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyAlignment\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyProtection\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"cellStyle\" type=\"CT_CellStyle\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"required\"/>\n    <xsd:attribute name=\"builtinId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iLevel\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"customBuiltin\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxfs\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxf\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumFmtId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellStyleXfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DxfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:element name=\"indexedColors\" type=\"CT_IndexedColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mruColors\" type=\"CT_MRUColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IndexedColors\">\n    <xsd:sequence>\n      <xsd:element name=\"rgbColor\" type=\"CT_RgbColor\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MRUColors\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RgbColor\">\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultTableStyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultPivotStyle\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyleElement\" type=\"CT_TableStyleElement\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"table\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TableStyleType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableStyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"headerRow\"/>\n      <xsd:enumeration value=\"totalRow\"/>\n      <xsd:enumeration value=\"firstColumn\"/>\n      <xsd:enumeration value=\"lastColumn\"/>\n      <xsd:enumeration value=\"firstRowStripe\"/>\n      <xsd:enumeration value=\"secondRowStripe\"/>\n      <xsd:enumeration value=\"firstColumnStripe\"/>\n      <xsd:enumeration value=\"secondColumnStripe\"/>\n      <xsd:enumeration value=\"firstHeaderCell\"/>\n      <xsd:enumeration value=\"lastHeaderCell\"/>\n      <xsd:enumeration value=\"firstTotalCell\"/>\n      <xsd:enumeration value=\"lastTotalCell\"/>\n      <xsd:enumeration value=\"firstSubtotalColumn\"/>\n      <xsd:enumeration value=\"secondSubtotalColumn\"/>\n      <xsd:enumeration value=\"thirdSubtotalColumn\"/>\n      <xsd:enumeration value=\"firstSubtotalRow\"/>\n      <xsd:enumeration value=\"secondSubtotalRow\"/>\n      <xsd:enumeration value=\"thirdSubtotalRow\"/>\n      <xsd:enumeration value=\"blankRow\"/>\n      <xsd:enumeration value=\"firstColumnSubheading\"/>\n      <xsd:enumeration value=\"secondColumnSubheading\"/>\n      <xsd:enumeration value=\"thirdColumnSubheading\"/>\n      <xsd:enumeration value=\"firstRowSubheading\"/>\n      <xsd:enumeration value=\"secondRowSubheading\"/>\n      <xsd:enumeration value=\"thirdRowSubheading\"/>\n      <xsd:enumeration value=\"pageFieldLabels\"/>\n      <xsd:enumeration value=\"pageFieldValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BooleanProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSize\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IntProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignFontProperty\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:attribute name=\"val\" type=\"ST_FontScheme\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontScheme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnderlineProperty\">\n    <xsd:attribute name=\"val\" type=\"ST_UnderlineValues\" use=\"optional\" default=\"single\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnderlineValues\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"singleAccounting\"/>\n      <xsd:enumeration value=\"doubleAccounting\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"14\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_AutoFormat\">\n    <xsd:attribute name=\"autoFormatId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"applyNumberFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyBorderFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyFontFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyPatternFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyAlignmentFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyWidthHeightFormats\" type=\"xsd:boolean\"/>\n  </xsd:attributeGroup>\n  <xsd:element name=\"externalLink\" type=\"CT_ExternalLink\"/>\n  <xsd:complexType name=\"CT_ExternalLink\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"externalBook\" type=\"CT_ExternalBook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ddeLink\" type=\"CT_DdeLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"oleLink\" type=\"CT_OleLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalBook\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetNames\" type=\"CT_ExternalSheetNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_ExternalDefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetDataSet\" type=\"CT_ExternalSheetDataSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetNames\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetName\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_ExternalSheetName\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_ExternalDefinedName\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedName\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"refersTo\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetDataSet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetData\" type=\"CT_ExternalSheetData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_ExternalRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"refreshError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalRow\">\n    <xsd:sequence>\n      <xsd:element name=\"cell\" type=\"CT_ExternalCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalCell\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeLink\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItems\" type=\"CT_DdeItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ddeService\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"ddeTopic\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItems\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItem\" type=\"CT_DdeItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItem\">\n    <xsd:sequence>\n      <xsd:element name=\"values\" type=\"CT_DdeValues\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" default=\"0\"/>\n    <xsd:attribute name=\"ole\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValues\">\n    <xsd:sequence>\n      <xsd:element name=\"value\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_DdeValue\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rows\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cols\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_DdeValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DdeValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"str\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleLink\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItems\" type=\"CT_OleItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItems\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItem\" type=\"CT_OleItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"icon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"table\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableColumns\" type=\"CT_TableColumns\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyleInfo\" type=\"CT_TableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"displayName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"tableType\" type=\"ST_TableType\" use=\"optional\" default=\"worksheet\"/>\n    <xsd:attribute name=\"headerRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"insertRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"insertRowShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"totalsRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"totalsRowShown\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"tableBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"xml\"/>\n      <xsd:enumeration value=\"queryTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleInfo\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showFirstColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showColumnStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumns\">\n    <xsd:sequence>\n      <xsd:element name=\"tableColumn\" type=\"CT_TableColumn\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumn\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedColumnFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"totalsRowFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xmlColumnPr\" type=\"CT_XmlColumnPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"totalsRowFunction\" type=\"ST_TotalsRowFunction\" use=\"optional\"\n      default=\"none\"/>\n    <xsd:attribute name=\"totalsRowLabel\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"queryTableFieldId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"array\" type=\"xsd:boolean\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TotalsRowFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XmlColumnPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"denormalized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_XmlDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:element name=\"volTypes\" type=\"CT_VolTypes\"/>\n  <xsd:complexType name=\"CT_VolTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"volType\" type=\"CT_VolType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolType\">\n    <xsd:sequence>\n      <xsd:element name=\"main\" type=\"CT_VolMain\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_VolDepType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolMain\">\n    <xsd:sequence>\n      <xsd:element name=\"tp\" type=\"CT_VolTopic\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"first\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopic\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stp\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tr\" type=\"CT_VolTopicRef\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_VolValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopicRef\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VolDepType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"realTimeData\"/>\n      <xsd:enumeration value=\"olapFunctions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VolValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"workbook\" type=\"CT_Workbook\"/>\n  <xsd:complexType name=\"CT_Workbook\">\n    <xsd:sequence>\n      <xsd:element name=\"fileVersion\" type=\"CT_FileVersion\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileSharing\" type=\"CT_FileSharing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookPr\" type=\"CT_WorkbookPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookProtection\" type=\"CT_WorkbookProtection\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"bookViews\" type=\"CT_BookViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheets\" type=\"CT_Sheets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"functionGroups\" type=\"CT_FunctionGroups\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalReferences\" type=\"CT_ExternalReferences\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_DefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"calcPr\" type=\"CT_CalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleSize\" type=\"CT_OleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customWorkbookViews\" type=\"CT_CustomWorkbookViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotCaches\" type=\"CT_PivotCaches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagTypes\" type=\"CT_SmartTagTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishing\" type=\"CT_WebPublishing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileRecoveryPr\" type=\"CT_FileRecoveryPr\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"webPublishObjects\" type=\"CT_WebPublishObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileVersion\">\n    <xsd:attribute name=\"appName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lastEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lowestEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rupBuild\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"codeName\" type=\"s:ST_Guid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"workbookView\" type=\"CT_BookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"visibility\" type=\"ST_Visibility\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"firstSheet\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"activeTab\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"autoFilterDateGrouping\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Visibility\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CustomWorkbookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customWorkbookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomWorkbookView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomWorkbookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"autoUpdate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"mergeInterval\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"changesSavedWin\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"onlySync\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"personalView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"includePrintSettings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"includeHiddenRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"maximized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"activeSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"showFormulaBar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showStatusbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showComments\" type=\"ST_Comments\" use=\"optional\" default=\"commIndicator\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Comments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"commNone\"/>\n      <xsd:enumeration value=\"commIndicator\"/>\n      <xsd:enumeration value=\"commIndAndComment\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Objects\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"placeholders\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Sheets\">\n    <xsd:sequence>\n      <xsd:element name=\"sheet\" type=\"CT_Sheet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sheet\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorkbookPr\">\n    <xsd:attribute name=\"date1904\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"showBorderUnselectedTables\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n    <xsd:attribute name=\"filterPrivacy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"promptedSolutions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInkAnnotation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"backupFile\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveExternalLinkValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"updateLinks\" type=\"ST_UpdateLinks\" use=\"optional\" default=\"userSet\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hidePivotFieldList\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPivotChartFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"allowRefreshQuery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"publishItems\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"checkCompatibility\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshAllConnections\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultThemeVersion\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UpdateLinks\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"userSet\"/>\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:attribute name=\"embed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"show\" type=\"ST_SmartTagShow\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SmartTagShow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"noIndicator\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceUri\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileRecoveryPr\">\n    <xsd:attribute name=\"autoRecover\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"crashSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dataExtractLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"repairLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcPr\">\n    <xsd:attribute name=\"calcId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"calcMode\" type=\"ST_CalcMode\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refMode\" type=\"ST_RefMode\" use=\"optional\" default=\"A1\"/>\n    <xsd:attribute name=\"iterate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"iterateCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"iterateDelta\" type=\"xsd:double\" use=\"optional\" default=\"0.001\"/>\n    <xsd:attribute name=\"fullPrecision\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcCompleted\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentCalc\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentManualCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"forceFullCalc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CalcMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"autoNoTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"A1\"/>\n      <xsd:enumeration value=\"R1C1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_DefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefinedName\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n        <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"vbProcedure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"xlm\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"shortcutKey\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"publishToServer\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"workbookParameter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"externalReference\" type=\"CT_ExternalReference\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReference\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetBackgroundPicture\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCaches\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotCache\" type=\"CT_PivotCache\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCache\">\n    <xsd:attribute name=\"cacheId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileSharing\">\n    <xsd:attribute name=\"readOnlyRecommended\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"reservationPassword\" type=\"ST_UnsignedShortHex\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleSize\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WorkbookProtection\">\n    <xsd:attribute name=\"workbookPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lockStructure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockWindows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockRevision\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"revisionsAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishing\">\n    <xsd:attribute name=\"css\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"thicket\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"longFileNames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"vml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"targetScreenSize\" type=\"ST_TargetScreenSize\" use=\"optional\"\n      default=\"800x600\"/>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"96\"/>\n    <xsd:attribute name=\"codePage\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FunctionGroups\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"functionGroup\" type=\"CT_FunctionGroup\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"builtInGroupCount\" type=\"xsd:unsignedInt\" default=\"16\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FunctionGroup\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishObject\" type=\"CT_WebPublishObject\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObject\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:schemas-microsoft-com:vml\"\n  xmlns:pvml=\"urn:schemas-microsoft-com:office:powerpoint\"\n  xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:w10=\"urn:schemas-microsoft-com:office:word\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:vml\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:office\"\n    schemaLocation=\"vml-officeDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:word\"\n    schemaLocation=\"vml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:excel\"\n    schemaLocation=\"vml-spreadsheetDrawing.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:powerpoint\"\n    schemaLocation=\"vml-presentationDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attributeGroup name=\"AG_Id\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Style\">\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Type\">\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Adj\">\n    <xsd:attribute name=\"adj\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Path\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Fill\">\n    <xsd:attribute name=\"filled\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Chromakey\">\n    <xsd:attribute name=\"chromakey\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Ext\">\n    <xsd:attribute name=\"ext\" form=\"qualified\" type=\"ST_Ext\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_CoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"href\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"class\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"alt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordsize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"print\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"stroked\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeweight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeCoreAttributes\">\n    <xsd:attribute ref=\"o:spid\"/>\n    <xsd:attribute ref=\"o:oned\"/>\n    <xsd:attribute ref=\"o:regroupid\"/>\n    <xsd:attribute ref=\"o:doubleclicknotify\"/>\n    <xsd:attribute ref=\"o:button\"/>\n    <xsd:attribute ref=\"o:userhidden\"/>\n    <xsd:attribute ref=\"o:bullet\"/>\n    <xsd:attribute ref=\"o:hr\"/>\n    <xsd:attribute ref=\"o:hrstd\"/>\n    <xsd:attribute ref=\"o:hrnoshade\"/>\n    <xsd:attribute ref=\"o:hrpct\"/>\n    <xsd:attribute ref=\"o:hralign\"/>\n    <xsd:attribute ref=\"o:allowincell\"/>\n    <xsd:attribute ref=\"o:allowoverlap\"/>\n    <xsd:attribute ref=\"o:userdrawn\"/>\n    <xsd:attribute ref=\"o:bordertopcolor\"/>\n    <xsd:attribute ref=\"o:borderleftcolor\"/>\n    <xsd:attribute ref=\"o:borderbottomcolor\"/>\n    <xsd:attribute ref=\"o:borderrightcolor\"/>\n    <xsd:attribute ref=\"o:dgmlayout\"/>\n    <xsd:attribute ref=\"o:dgmnodekind\"/>\n    <xsd:attribute ref=\"o:dgmlayoutmru\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeShapeAttributes\">\n    <xsd:attribute ref=\"o:spt\"/>\n    <xsd:attribute ref=\"o:connectortype\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"o:oleicon\"/>\n    <xsd:attribute ref=\"o:ole\"/>\n    <xsd:attribute ref=\"o:preferrelative\"/>\n    <xsd:attribute ref=\"o:cliptowrap\"/>\n    <xsd:attribute ref=\"o:clip\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllCoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_CoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeCoreAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_ShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeShapeAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ImageAttributes\">\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropleft\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"croptop\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropright\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropbottom\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gain\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"blacklevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gamma\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"grayscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"bilevel\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_StrokeAttributes\">\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n  </xsd:attributeGroup>\n  <xsd:group name=\"EG_ShapeElements\">\n    <xsd:choice>\n      <xsd:element ref=\"path\"/>\n      <xsd:element ref=\"formulas\"/>\n      <xsd:element ref=\"handles\"/>\n      <xsd:element ref=\"fill\"/>\n      <xsd:element ref=\"stroke\"/>\n      <xsd:element ref=\"shadow\"/>\n      <xsd:element ref=\"textbox\"/>\n      <xsd:element ref=\"textpath\"/>\n      <xsd:element ref=\"imagedata\"/>\n      <xsd:element ref=\"o:skew\"/>\n      <xsd:element ref=\"o:extrusion\"/>\n      <xsd:element ref=\"o:callout\"/>\n      <xsd:element ref=\"o:lock\"/>\n      <xsd:element ref=\"o:clippath\"/>\n      <xsd:element ref=\"o:signatureline\"/>\n      <xsd:element ref=\"w10:wrap\"/>\n      <xsd:element ref=\"w10:anchorlock\"/>\n      <xsd:element ref=\"w10:bordertop\"/>\n      <xsd:element ref=\"w10:borderbottom\"/>\n      <xsd:element ref=\"w10:borderleft\"/>\n      <xsd:element ref=\"w10:borderright\"/>\n      <xsd:element ref=\"x:ClientData\" minOccurs=\"0\"/>\n      <xsd:element ref=\"pvml:textdata\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"shape\" type=\"CT_Shape\"/>\n  <xsd:element name=\"shapetype\" type=\"CT_Shapetype\"/>\n  <xsd:element name=\"group\" type=\"CT_Group\"/>\n  <xsd:element name=\"background\" type=\"CT_Background\"/>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n      <xsd:element ref=\"pvml:iscomment\"/>\n      <xsd:element ref=\"o:equationxml\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Type\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:gfxdata\"/>\n    <xsd:attribute name=\"equationxml\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shapetype\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"o:complex\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:master\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Group\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"group\"/>\n      <xsd:element ref=\"shape\"/>\n      <xsd:element ref=\"shapetype\"/>\n      <xsd:element ref=\"arc\"/>\n      <xsd:element ref=\"curve\"/>\n      <xsd:element ref=\"image\"/>\n      <xsd:element ref=\"line\"/>\n      <xsd:element ref=\"oval\"/>\n      <xsd:element ref=\"polyline\"/>\n      <xsd:element ref=\"rect\"/>\n      <xsd:element ref=\"roundrect\"/>\n      <xsd:element ref=\"o:diagram\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"editas\" type=\"ST_EditAs\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:tableproperties\"/>\n    <xsd:attribute ref=\"o:tablelimits\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:element ref=\"fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:targetscreensize\"/>\n  </xsd:complexType>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:element name=\"formulas\" type=\"CT_Formulas\"/>\n  <xsd:element name=\"handles\" type=\"CT_Handles\"/>\n  <xsd:element name=\"imagedata\" type=\"CT_ImageData\"/>\n  <xsd:element name=\"path\" type=\"CT_Path\"/>\n  <xsd:element name=\"textbox\" type=\"CT_Textbox\"/>\n  <xsd:element name=\"shadow\" type=\"CT_Shadow\"/>\n  <xsd:element name=\"stroke\" type=\"CT_Stroke\"/>\n  <xsd:element name=\"textpath\" type=\"CT_TextPath\"/>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"position\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"aspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"alignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"focus\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focussize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focusposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"method\" type=\"ST_FillMethod\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:opacity2\"/>\n    <xsd:attribute name=\"recolor\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotate\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formulas\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_F\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:attribute name=\"eqn\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Handles\">\n    <xsd:sequence>\n      <xsd:element name=\"h\" type=\"CT_H\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_H\">\n    <xsd:attribute name=\"position\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"polar\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"map\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"invx\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"invy\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"switch\" type=\"s:ST_TrueFalseBlank\"/>\n    <xsd:attribute name=\"xrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"yrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"radiusrange\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ImageData\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attribute name=\"embosscolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"recolortarget\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:oleid\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:movie\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n    <xsd:attribute ref=\"r:id\"/>\n    <xsd:attribute ref=\"r:pict\"/>\n    <xsd:attribute ref=\"r:href\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"limo\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textboxrect\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fillok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shadowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"arrowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"gradientshapeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textpathok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpenok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:connecttype\"/>\n    <xsd:attribute ref=\"o:connectlocs\"/>\n    <xsd:attribute ref=\"o:connectangles\"/>\n    <xsd:attribute ref=\"o:extrusionok\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shadow\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ShadowType\" use=\"optional\"/>\n    <xsd:attribute name=\"obscured\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"offset2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Stroke\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:left\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:top\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:right\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:bottom\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:column\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_StrokeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Textbox\">\n    <xsd:choice>\n      <xsd:element ref=\"w:txbxContent\" minOccurs=\"0\"/>\n      <xsd:any namespace=\"##local\" processContents=\"skip\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"inset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:singleclick\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextPath\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitpath\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"trim\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"xscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"string\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"arc\" type=\"CT_Arc\"/>\n  <xsd:element name=\"curve\" type=\"CT_Curve\"/>\n  <xsd:element name=\"image\" type=\"CT_Image\"/>\n  <xsd:element name=\"line\" type=\"CT_Line\"/>\n  <xsd:element name=\"oval\" type=\"CT_Oval\"/>\n  <xsd:element name=\"polyline\" type=\"CT_PolyLine\"/>\n  <xsd:element name=\"rect\" type=\"CT_Rect\"/>\n  <xsd:element name=\"roundrect\" type=\"CT_RoundRect\"/>\n  <xsd:complexType name=\"CT_Arc\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"startAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"endAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Curve\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control1\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Image\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Oval\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolyLine\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"points\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RoundRect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"arcsize\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Ext\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"view\"/>\n      <xsd:enumeration value=\"edit\"/>\n      <xsd:enumeration value=\"backwardCompatible\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"frame\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"sigma\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"linear sigma\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ShadowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"emboss\"/>\n      <xsd:enumeration value=\"perspective\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeLineStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thinThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeJoinStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"miter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeEndCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"round\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowLength\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"short\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"long\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"narrow\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"wide\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"block\"/>\n      <xsd:enumeration value=\"classic\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"open\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ImageAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ignore\"/>\n      <xsd:enumeration value=\"atMost\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"canvas\"/>\n      <xsd:enumeration value=\"orgchart\"/>\n      <xsd:enumeration value=\"radial\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"stacked\"/>\n      <xsd:enumeration value=\"venn\"/>\n      <xsd:enumeration value=\"bullseye\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:office\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:vml\" schemaLocation=\"vml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attribute name=\"bwmode\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwpure\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwnormal\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"targetscreensize\" type=\"ST_ScreenSize\"/>\n  <xsd:attribute name=\"insetmode\" type=\"ST_InsetMode\" default=\"custom\"/>\n  <xsd:attribute name=\"spt\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"oned\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"regroupid\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"doubleclicknotify\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"connectortype\" type=\"ST_ConnectorType\" default=\"straight\"/>\n  <xsd:attribute name=\"button\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userhidden\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"forcedash\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleicon\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"ole\" type=\"s:ST_TrueFalseBlank\"/>\n  <xsd:attribute name=\"preferrelative\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"cliptowrap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"clip\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bullet\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hr\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrstd\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrnoshade\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrpct\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"hralign\" type=\"ST_HrAlign\" default=\"left\"/>\n  <xsd:attribute name=\"allowincell\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"allowoverlap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userdrawn\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bordertopcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderleftcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderbottomcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderrightcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connecttype\" type=\"ST_ConnectType\"/>\n  <xsd:attribute name=\"connectlocs\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connectangles\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"master\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"extrusionok\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"href\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"althref\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"title\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"singleclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleid\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"detectmouseclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"movie\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"spid\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"opacity2\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"relid\" type=\"r:ST_RelationshipId\"/>\n  <xsd:attribute name=\"dgmlayout\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"dgmnodekind\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"dgmlayoutmru\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"gfxdata\" type=\"xsd:base64Binary\"/>\n  <xsd:attribute name=\"tableproperties\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"tablelimits\" type=\"xsd:string\"/>\n  <xsd:element name=\"shapedefaults\" type=\"CT_ShapeDefaults\"/>\n  <xsd:element name=\"shapelayout\" type=\"CT_ShapeLayout\"/>\n  <xsd:element name=\"signatureline\" type=\"CT_SignatureLine\"/>\n  <xsd:element name=\"ink\" type=\"CT_Ink\"/>\n  <xsd:element name=\"diagram\" type=\"CT_Diagram\"/>\n  <xsd:element name=\"equationxml\" type=\"CT_EquationXml\"/>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:all minOccurs=\"0\">\n      <xsd:element ref=\"v:fill\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:stroke\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:textbox\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:shadow\" minOccurs=\"0\"/>\n      <xsd:element ref=\"skew\" minOccurs=\"0\"/>\n      <xsd:element ref=\"extrusion\" minOccurs=\"0\"/>\n      <xsd:element ref=\"callout\" minOccurs=\"0\"/>\n      <xsd:element ref=\"lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"colormru\" minOccurs=\"0\" type=\"CT_ColorMru\"/>\n      <xsd:element name=\"colormenu\" minOccurs=\"0\" type=\"CT_ColorMenu\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"spidmax\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"stroke\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"allowincell\" form=\"qualified\" type=\"s:ST_TrueFalse\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ink\">\n    <xsd:sequence/>\n    <xsd:attribute name=\"i\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"annotation\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"contentType\" type=\"ST_ContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SignatureLine\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"issignatureline\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"provid\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"signinginstructionsset\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"allowcomments\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"showsigndate\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"suggestedsigner\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigner2\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigneremail\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"signinginstructions\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"addlxml\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"sigprovurl\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLayout\">\n    <xsd:all>\n      <xsd:element name=\"idmap\" type=\"CT_IdMap\" minOccurs=\"0\"/>\n      <xsd:element name=\"regrouptable\" type=\"CT_RegroupTable\" minOccurs=\"0\"/>\n      <xsd:element name=\"rules\" type=\"CT_Rules\" minOccurs=\"0\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IdMap\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RegroupTable\">\n    <xsd:sequence>\n      <xsd:element name=\"entry\" type=\"CT_Entry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Entry\">\n    <xsd:attribute name=\"new\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" type=\"CT_R\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"proxy\" type=\"CT_Proxy\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_RType\" use=\"optional\"/>\n    <xsd:attribute name=\"how\" type=\"ST_How\" use=\"optional\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Proxy\">\n    <xsd:attribute name=\"start\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"end\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"connectloc\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Diagram\">\n    <xsd:sequence>\n      <xsd:element name=\"relationtable\" type=\"CT_RelationTable\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"dgmstyle\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"autoformat\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"reverse\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autolayout\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscalex\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscaley\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmfontsize\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"constrainbounds\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmbasetextscale\" type=\"xsd:integer\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EquationXml\">\n    <xsd:sequence>\n      <xsd:any namespace=\"##any\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"contentType\" type=\"ST_AlternateMathContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlternateMathContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RelationTable\">\n    <xsd:sequence>\n      <xsd:element name=\"rel\" type=\"CT_Relation\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Relation\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"idsrc\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"iddest\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"idcntr\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMru\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMenu\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"shadowcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"extrusioncolor\" type=\"s:ST_ColorType\"/>\n  </xsd:complexType>\n  <xsd:element name=\"skew\" type=\"CT_Skew\"/>\n  <xsd:element name=\"extrusion\" type=\"CT_Extrusion\"/>\n  <xsd:element name=\"callout\" type=\"CT_Callout\"/>\n  <xsd:element name=\"lock\" type=\"CT_Lock\"/>\n  <xsd:element name=\"OLEObject\" type=\"CT_OLEObject\"/>\n  <xsd:element name=\"complex\" type=\"CT_Complex\"/>\n  <xsd:element name=\"left\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"top\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"right\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"bottom\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"column\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"clippath\" type=\"CT_ClipPath\"/>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:complexType name=\"CT_Skew\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extrusion\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ExtrusionType\" default=\"parallel\" use=\"optional\"/>\n    <xsd:attribute name=\"render\" type=\"ST_ExtrusionRender\" default=\"solid\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpointorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpoint\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"plane\" type=\"ST_ExtrusionPlane\" default=\"XY\" use=\"optional\"/>\n    <xsd:attribute name=\"skewangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"skewamt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"foredepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"backdepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientation\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientationangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"lockrotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autorotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationcenter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationangle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"colormode\" type=\"ST_ColorMode\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"shininess\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"specularity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"diffusity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"metal\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"facet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightface\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"brightness\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh2\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Callout\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gap\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"dropauto\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"drop\" type=\"ST_CalloutDrop\" use=\"optional\"/>\n    <xsd:attribute name=\"distance\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lengthspecified\" type=\"s:ST_TrueFalse\" default=\"f\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"accentbar\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textborder\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusx\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusy\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"position\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"selection\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"grouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"ungrouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotation\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"cropping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"verticies\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"adjusthandles\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"aspectratio\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shapetype\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OLEObject\">\n    <xsd:sequence>\n      <xsd:element name=\"LinkType\" type=\"ST_OLELinkType\" minOccurs=\"0\"/>\n      <xsd:element name=\"LockedField\" type=\"s:ST_TrueFalseBlank\" minOccurs=\"0\"/>\n      <xsd:element name=\"FieldCodes\" type=\"xsd:string\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"Type\" type=\"ST_OLEType\" use=\"optional\"/>\n    <xsd:attribute name=\"ProgID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"ShapeID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DrawAspect\" type=\"ST_OLEDrawAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"ObjectID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"UpdateMode\" type=\"ST_OLEUpdateMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Complex\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrokeChild\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"v:ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"v:ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"v:ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"v:ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"v:ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"href\"/>\n    <xsd:attribute ref=\"althref\"/>\n    <xsd:attribute ref=\"title\"/>\n    <xsd:attribute ref=\"forcedash\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipPath\">\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"required\" form=\"qualified\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"callout\"/>\n      <xsd:enumeration value=\"connector\"/>\n      <xsd:enumeration value=\"align\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_How\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"middle\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BWMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"color\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"grayScale\"/>\n      <xsd:enumeration value=\"lightGrayscale\"/>\n      <xsd:enumeration value=\"inverseGray\"/>\n      <xsd:enumeration value=\"grayOutline\"/>\n      <xsd:enumeration value=\"highContrast\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hide\"/>\n      <xsd:enumeration value=\"undrawn\"/>\n      <xsd:enumeration value=\"blackTextAndLines\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544,376\"/>\n      <xsd:enumeration value=\"640,480\"/>\n      <xsd:enumeration value=\"720,512\"/>\n      <xsd:enumeration value=\"800,600\"/>\n      <xsd:enumeration value=\"1024,768\"/>\n      <xsd:enumeration value=\"1152,862\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InsetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramLayout\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:enumeration value=\"0\"/>\n      <xsd:enumeration value=\"1\"/>\n      <xsd:enumeration value=\"2\"/>\n      <xsd:enumeration value=\"3\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"perspective\"/>\n      <xsd:enumeration value=\"parallel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionRender\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"wireFrame\"/>\n      <xsd:enumeration value=\"boundingCube\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionPlane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"XY\"/>\n      <xsd:enumeration value=\"ZX\"/>\n      <xsd:enumeration value=\"YZ\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"30\"/>\n      <xsd:enumeration value=\"45\"/>\n      <xsd:enumeration value=\"60\"/>\n      <xsd:enumeration value=\"90\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutDrop\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutPlacement\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"user\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"straight\"/>\n      <xsd:enumeration value=\"elbow\"/>\n      <xsd:enumeration value=\"curved\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HrAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"segments\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLELinkType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Embed\"/>\n      <xsd:enumeration value=\"Link\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Content\"/>\n      <xsd:enumeration value=\"Icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Always\"/>\n      <xsd:enumeration value=\"OnCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gradientCenter\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"gradientUnscaled\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"background\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:powerpoint\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:powerpoint\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"iscomment\" type=\"CT_Empty\"/>\n  <xsd:element name=\"textdata\" type=\"CT_Rel\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:excel\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"ClientData\" type=\"CT_ClientData\"/>\n  <xsd:complexType name=\"CT_ClientData\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"MoveWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SizeWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Anchor\" type=\"xsd:string\"/>\n      <xsd:element name=\"Locked\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DefaultSize\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"PrintObject\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Disabled\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoFill\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoPict\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaMacro\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextHAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextVAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"LockText\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"JustLastX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SecretEdit\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Default\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Help\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Cancel\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dismiss\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Accel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Accel2\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Row\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Column\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Visible\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RowHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ColHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VTEdit\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MultiLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VScroll\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ValidIds\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaRange\" type=\"xsd:string\"/>\n      <xsd:element name=\"WidthMin\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Sel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"NoThreeD2\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SelType\" type=\"xsd:string\"/>\n      <xsd:element name=\"MultiSel\" type=\"xsd:string\"/>\n      <xsd:element name=\"LCT\" type=\"xsd:string\"/>\n      <xsd:element name=\"ListItem\" type=\"xsd:string\"/>\n      <xsd:element name=\"DropStyle\" type=\"xsd:string\"/>\n      <xsd:element name=\"Colored\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DropLines\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Checked\" type=\"xsd:integer\"/>\n      <xsd:element name=\"FmlaLink\" type=\"xsd:string\"/>\n      <xsd:element name=\"FmlaPict\" type=\"xsd:string\"/>\n      <xsd:element name=\"NoThreeD\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FirstButton\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaGroup\" type=\"xsd:string\"/>\n      <xsd:element name=\"Val\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Min\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Max\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Inc\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Page\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Horiz\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dx\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MapOCX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"CF\" type=\"ST_CF\"/>\n      <xsd:element name=\"Camera\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RecalcAlways\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoScale\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DDE\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"UIObj\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ScriptText\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptExtended\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptLanguage\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"ScriptLocation\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"FmlaTxbx\" type=\"xsd:string\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"ObjectType\" type=\"ST_ObjectType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CF\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ObjectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Button\"/>\n      <xsd:enumeration value=\"Checkbox\"/>\n      <xsd:enumeration value=\"Dialog\"/>\n      <xsd:enumeration value=\"Drop\"/>\n      <xsd:enumeration value=\"Edit\"/>\n      <xsd:enumeration value=\"GBox\"/>\n      <xsd:enumeration value=\"Label\"/>\n      <xsd:enumeration value=\"LineA\"/>\n      <xsd:enumeration value=\"List\"/>\n      <xsd:enumeration value=\"Movie\"/>\n      <xsd:enumeration value=\"Note\"/>\n      <xsd:enumeration value=\"Pict\"/>\n      <xsd:enumeration value=\"Radio\"/>\n      <xsd:enumeration value=\"RectA\"/>\n      <xsd:enumeration value=\"Scroll\"/>\n      <xsd:enumeration value=\"Spin\"/>\n      <xsd:enumeration value=\"Shape\"/>\n      <xsd:enumeration value=\"Group\"/>\n      <xsd:enumeration value=\"Rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:word\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:word\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"bordertop\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderleft\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderright\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderbottom\" type=\"CT_Border\"/>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"type\" type=\"ST_BorderType\" use=\"optional\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:positiveInteger\" use=\"optional\"/>\n    <xsd:attribute name=\"shadow\" type=\"ST_BorderShadow\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"wrap\" type=\"CT_Wrap\"/>\n  <xsd:complexType name=\"CT_Wrap\">\n    <xsd:attribute name=\"type\" type=\"ST_WrapType\" use=\"optional\"/>\n    <xsd:attribute name=\"side\" type=\"ST_WrapSide\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorx\" type=\"ST_HorizontalAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"anchory\" type=\"ST_VerticalAnchor\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"anchorlock\" type=\"CT_AnchorLock\"/>\n  <xsd:complexType name=\"CT_AnchorLock\"/>\n  <xsd:simpleType name=\"ST_BorderType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hairline\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmall\"/>\n      <xsd:enumeration value=\"thickThinSmall\"/>\n      <xsd:enumeration value=\"thickBetweenThinSmall\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n      <xsd:enumeration value=\"thinThickLarge\"/>\n      <xsd:enumeration value=\"thickThinLarge\"/>\n      <xsd:enumeration value=\"thickBetweenThinLarge\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashedSmall\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"HTMLOutset\"/>\n      <xsd:enumeration value=\"HTMLInset\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderShadow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"topAndBottom\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapSide\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"char\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"line\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:sl=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" schemaLocation=\"../mce/mc.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n    schemaLocation=\"dml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n    schemaLocation=\"shared-math.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n    schemaLocation=\"shared-customXmlSchemaProperties.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LongHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LongHexNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_LongHexNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShortHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UcharHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Charset\">\n    <xsd:attribute name=\"val\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"s:ST_String\" use=\"optional\" default=\"ISO-8859-1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DecimalNumberOrPercent\">\n    <xsd:union memberTypes=\"ST_UnqualifiedPercentage s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnqualifiedPercentage\">\n    <xsd:restriction base=\"xsd:decimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DecimalNumber\">\n    <xsd:restriction base=\"xsd:integer\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedDecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DecimalNumberOrPrecent\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedTwipsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedTwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PixelsMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PixelsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HpsMeasure\">\n    <xsd:union memberTypes=\"s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_HpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedHpsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedHpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedHpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTime\">\n    <xsd:restriction base=\"xsd:dateTime\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_MacroName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"33\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MacroName\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MacroName\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EighthPointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextScale\">\n    <xsd:union memberTypes=\"ST_TextScalePercent ST_TextScaleDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(600|([0-5]?[0-9]?[0-9]))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScaleDecimal\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"600\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextScale\">\n    <xsd:attribute name=\"val\" type=\"ST_TextScale\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HighlightColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkYellow\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Highlight\">\n    <xsd:attribute name=\"val\" type=\"ST_HighlightColor\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HexColorAuto\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColor\">\n    <xsd:union memberTypes=\"ST_HexColorAuto s:ST_HexColorRGB\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"val\" type=\"ST_HexColor\" use=\"required\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lang\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guid\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Guid\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Underline\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashedHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dashDotDotHeavy\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDouble\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Underline\">\n    <xsd:attribute name=\"val\" type=\"ST_Underline\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextEffect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blinkBackground\"/>\n      <xsd:enumeration value=\"lights\"/>\n      <xsd:enumeration value=\"antsBlack\"/>\n      <xsd:enumeration value=\"antsRed\"/>\n      <xsd:enumeration value=\"shimmer\"/>\n      <xsd:enumeration value=\"sparkle\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextEffect\">\n    <xsd:attribute name=\"val\" type=\"ST_TextEffect\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Border\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmallGap\"/>\n      <xsd:enumeration value=\"thickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickMediumGap\"/>\n      <xsd:enumeration value=\"thickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickLargeGap\"/>\n      <xsd:enumeration value=\"thickThinLargeGap\"/>\n      <xsd:enumeration value=\"thinThickThinLargeGap\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashSmallGap\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"outset\"/>\n      <xsd:enumeration value=\"inset\"/>\n      <xsd:enumeration value=\"apples\"/>\n      <xsd:enumeration value=\"archedScallops\"/>\n      <xsd:enumeration value=\"babyPacifier\"/>\n      <xsd:enumeration value=\"babyRattle\"/>\n      <xsd:enumeration value=\"balloons3Colors\"/>\n      <xsd:enumeration value=\"balloonsHotAir\"/>\n      <xsd:enumeration value=\"basicBlackDashes\"/>\n      <xsd:enumeration value=\"basicBlackDots\"/>\n      <xsd:enumeration value=\"basicBlackSquares\"/>\n      <xsd:enumeration value=\"basicThinLines\"/>\n      <xsd:enumeration value=\"basicWhiteDashes\"/>\n      <xsd:enumeration value=\"basicWhiteDots\"/>\n      <xsd:enumeration value=\"basicWhiteSquares\"/>\n      <xsd:enumeration value=\"basicWideInline\"/>\n      <xsd:enumeration value=\"basicWideMidline\"/>\n      <xsd:enumeration value=\"basicWideOutline\"/>\n      <xsd:enumeration value=\"bats\"/>\n      <xsd:enumeration value=\"birds\"/>\n      <xsd:enumeration value=\"birdsFlight\"/>\n      <xsd:enumeration value=\"cabins\"/>\n      <xsd:enumeration value=\"cakeSlice\"/>\n      <xsd:enumeration value=\"candyCorn\"/>\n      <xsd:enumeration value=\"celticKnotwork\"/>\n      <xsd:enumeration value=\"certificateBanner\"/>\n      <xsd:enumeration value=\"chainLink\"/>\n      <xsd:enumeration value=\"champagneBottle\"/>\n      <xsd:enumeration value=\"checkedBarBlack\"/>\n      <xsd:enumeration value=\"checkedBarColor\"/>\n      <xsd:enumeration value=\"checkered\"/>\n      <xsd:enumeration value=\"christmasTree\"/>\n      <xsd:enumeration value=\"circlesLines\"/>\n      <xsd:enumeration value=\"circlesRectangles\"/>\n      <xsd:enumeration value=\"classicalWave\"/>\n      <xsd:enumeration value=\"clocks\"/>\n      <xsd:enumeration value=\"compass\"/>\n      <xsd:enumeration value=\"confetti\"/>\n      <xsd:enumeration value=\"confettiGrays\"/>\n      <xsd:enumeration value=\"confettiOutline\"/>\n      <xsd:enumeration value=\"confettiStreamers\"/>\n      <xsd:enumeration value=\"confettiWhite\"/>\n      <xsd:enumeration value=\"cornerTriangles\"/>\n      <xsd:enumeration value=\"couponCutoutDashes\"/>\n      <xsd:enumeration value=\"couponCutoutDots\"/>\n      <xsd:enumeration value=\"crazyMaze\"/>\n      <xsd:enumeration value=\"creaturesButterfly\"/>\n      <xsd:enumeration value=\"creaturesFish\"/>\n      <xsd:enumeration value=\"creaturesInsects\"/>\n      <xsd:enumeration value=\"creaturesLadyBug\"/>\n      <xsd:enumeration value=\"crossStitch\"/>\n      <xsd:enumeration value=\"cup\"/>\n      <xsd:enumeration value=\"decoArch\"/>\n      <xsd:enumeration value=\"decoArchColor\"/>\n      <xsd:enumeration value=\"decoBlocks\"/>\n      <xsd:enumeration value=\"diamondsGray\"/>\n      <xsd:enumeration value=\"doubleD\"/>\n      <xsd:enumeration value=\"doubleDiamonds\"/>\n      <xsd:enumeration value=\"earth1\"/>\n      <xsd:enumeration value=\"earth2\"/>\n      <xsd:enumeration value=\"earth3\"/>\n      <xsd:enumeration value=\"eclipsingSquares1\"/>\n      <xsd:enumeration value=\"eclipsingSquares2\"/>\n      <xsd:enumeration value=\"eggsBlack\"/>\n      <xsd:enumeration value=\"fans\"/>\n      <xsd:enumeration value=\"film\"/>\n      <xsd:enumeration value=\"firecrackers\"/>\n      <xsd:enumeration value=\"flowersBlockPrint\"/>\n      <xsd:enumeration value=\"flowersDaisies\"/>\n      <xsd:enumeration value=\"flowersModern1\"/>\n      <xsd:enumeration value=\"flowersModern2\"/>\n      <xsd:enumeration value=\"flowersPansy\"/>\n      <xsd:enumeration value=\"flowersRedRose\"/>\n      <xsd:enumeration value=\"flowersRoses\"/>\n      <xsd:enumeration value=\"flowersTeacup\"/>\n      <xsd:enumeration value=\"flowersTiny\"/>\n      <xsd:enumeration value=\"gems\"/>\n      <xsd:enumeration value=\"gingerbreadMan\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"handmade1\"/>\n      <xsd:enumeration value=\"handmade2\"/>\n      <xsd:enumeration value=\"heartBalloon\"/>\n      <xsd:enumeration value=\"heartGray\"/>\n      <xsd:enumeration value=\"hearts\"/>\n      <xsd:enumeration value=\"heebieJeebies\"/>\n      <xsd:enumeration value=\"holly\"/>\n      <xsd:enumeration value=\"houseFunky\"/>\n      <xsd:enumeration value=\"hypnotic\"/>\n      <xsd:enumeration value=\"iceCreamCones\"/>\n      <xsd:enumeration value=\"lightBulb\"/>\n      <xsd:enumeration value=\"lightning1\"/>\n      <xsd:enumeration value=\"lightning2\"/>\n      <xsd:enumeration value=\"mapPins\"/>\n      <xsd:enumeration value=\"mapleLeaf\"/>\n      <xsd:enumeration value=\"mapleMuffins\"/>\n      <xsd:enumeration value=\"marquee\"/>\n      <xsd:enumeration value=\"marqueeToothed\"/>\n      <xsd:enumeration value=\"moons\"/>\n      <xsd:enumeration value=\"mosaic\"/>\n      <xsd:enumeration value=\"musicNotes\"/>\n      <xsd:enumeration value=\"northwest\"/>\n      <xsd:enumeration value=\"ovals\"/>\n      <xsd:enumeration value=\"packages\"/>\n      <xsd:enumeration value=\"palmsBlack\"/>\n      <xsd:enumeration value=\"palmsColor\"/>\n      <xsd:enumeration value=\"paperClips\"/>\n      <xsd:enumeration value=\"papyrus\"/>\n      <xsd:enumeration value=\"partyFavor\"/>\n      <xsd:enumeration value=\"partyGlass\"/>\n      <xsd:enumeration value=\"pencils\"/>\n      <xsd:enumeration value=\"people\"/>\n      <xsd:enumeration value=\"peopleWaving\"/>\n      <xsd:enumeration value=\"peopleHats\"/>\n      <xsd:enumeration value=\"poinsettias\"/>\n      <xsd:enumeration value=\"postageStamp\"/>\n      <xsd:enumeration value=\"pumpkin1\"/>\n      <xsd:enumeration value=\"pushPinNote2\"/>\n      <xsd:enumeration value=\"pushPinNote1\"/>\n      <xsd:enumeration value=\"pyramids\"/>\n      <xsd:enumeration value=\"pyramidsAbove\"/>\n      <xsd:enumeration value=\"quadrants\"/>\n      <xsd:enumeration value=\"rings\"/>\n      <xsd:enumeration value=\"safari\"/>\n      <xsd:enumeration value=\"sawtooth\"/>\n      <xsd:enumeration value=\"sawtoothGray\"/>\n      <xsd:enumeration value=\"scaredCat\"/>\n      <xsd:enumeration value=\"seattle\"/>\n      <xsd:enumeration value=\"shadowedSquares\"/>\n      <xsd:enumeration value=\"sharksTeeth\"/>\n      <xsd:enumeration value=\"shorebirdTracks\"/>\n      <xsd:enumeration value=\"skyrocket\"/>\n      <xsd:enumeration value=\"snowflakeFancy\"/>\n      <xsd:enumeration value=\"snowflakes\"/>\n      <xsd:enumeration value=\"sombrero\"/>\n      <xsd:enumeration value=\"southwest\"/>\n      <xsd:enumeration value=\"stars\"/>\n      <xsd:enumeration value=\"starsTop\"/>\n      <xsd:enumeration value=\"stars3d\"/>\n      <xsd:enumeration value=\"starsBlack\"/>\n      <xsd:enumeration value=\"starsShadowed\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"swirligig\"/>\n      <xsd:enumeration value=\"tornPaper\"/>\n      <xsd:enumeration value=\"tornPaperBlack\"/>\n      <xsd:enumeration value=\"trees\"/>\n      <xsd:enumeration value=\"triangleParty\"/>\n      <xsd:enumeration value=\"triangles\"/>\n      <xsd:enumeration value=\"triangle1\"/>\n      <xsd:enumeration value=\"triangle2\"/>\n      <xsd:enumeration value=\"triangleCircle1\"/>\n      <xsd:enumeration value=\"triangleCircle2\"/>\n      <xsd:enumeration value=\"shapes1\"/>\n      <xsd:enumeration value=\"shapes2\"/>\n      <xsd:enumeration value=\"twistedLines1\"/>\n      <xsd:enumeration value=\"twistedLines2\"/>\n      <xsd:enumeration value=\"vine\"/>\n      <xsd:enumeration value=\"waveline\"/>\n      <xsd:enumeration value=\"weavingAngles\"/>\n      <xsd:enumeration value=\"weavingBraid\"/>\n      <xsd:enumeration value=\"weavingRibbon\"/>\n      <xsd:enumeration value=\"weavingStrips\"/>\n      <xsd:enumeration value=\"whiteFlowers\"/>\n      <xsd:enumeration value=\"woodwork\"/>\n      <xsd:enumeration value=\"xIllusions\"/>\n      <xsd:enumeration value=\"zanyTriangles\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n      <xsd:enumeration value=\"zigZagStitch\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"val\" type=\"ST_Border\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_EighthPointMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"ST_PointMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"shadow\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"frame\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shd\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"horzStripe\"/>\n      <xsd:enumeration value=\"vertStripe\"/>\n      <xsd:enumeration value=\"reverseDiagStripe\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"horzCross\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"thinHorzStripe\"/>\n      <xsd:enumeration value=\"thinVertStripe\"/>\n      <xsd:enumeration value=\"thinReverseDiagStripe\"/>\n      <xsd:enumeration value=\"thinDiagStripe\"/>\n      <xsd:enumeration value=\"thinHorzCross\"/>\n      <xsd:enumeration value=\"thinDiagCross\"/>\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct12\"/>\n      <xsd:enumeration value=\"pct15\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct35\"/>\n      <xsd:enumeration value=\"pct37\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct45\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct55\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct62\"/>\n      <xsd:enumeration value=\"pct65\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct85\"/>\n      <xsd:enumeration value=\"pct87\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"pct95\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shd\">\n    <xsd:attribute name=\"val\" type=\"ST_Shd\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFill\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignRun\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FitText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Em\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"comma\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"underDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Em\">\n    <xsd:attribute name=\"val\" type=\"ST_Em\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Language\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"bidi\" type=\"s:ST_Lang\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CombineBrackets\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"curly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EastAsianLayout\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"combine\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"combineBrackets\" type=\"ST_CombineBrackets\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"vertCompress\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HeightRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Wrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"notBeside\"/>\n      <xsd:enumeration value=\"around\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DropCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"drop\"/>\n      <xsd:enumeration value=\"margin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FramePr\">\n    <xsd:attribute name=\"dropCap\" type=\"ST_DropCap\" use=\"optional\"/>\n    <xsd:attribute name=\"lines\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"vSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_Wrap\" use=\"optional\"/>\n    <xsd:attribute name=\"hAnchor\" type=\"ST_HAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"vAnchor\" type=\"ST_VAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"x\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"xAlign\" type=\"s:ST_XAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"y\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"yAlign\" type=\"s:ST_YAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorLock\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TabJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TabTlc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TabStop\">\n    <xsd:attribute name=\"val\" type=\"ST_TabJc\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_TabTlc\" use=\"optional\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LineSpacingRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Spacing\">\n    <xsd:attribute name=\"before\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"after\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"line\" type=\"ST_SignedTwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"lineRule\" type=\"ST_LineSpacingRule\" use=\"optional\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ind\">\n    <xsd:attribute name=\"start\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"startChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"end\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"endChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"left\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"leftChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"right\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"rightChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"hanging\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLine\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLineChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"mediumKashida\"/>\n      <xsd:enumeration value=\"distribute\"/>\n      <xsd:enumeration value=\"numTab\"/>\n      <xsd:enumeration value=\"highKashida\"/>\n      <xsd:enumeration value=\"lowKashida\"/>\n      <xsd:enumeration value=\"thaiDistribute\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_JcTable\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"start\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Jc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_JcTable\">\n    <xsd:attribute name=\"val\" type=\"ST_JcTable\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_View\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"outline\"/>\n      <xsd:enumeration value=\"masterPages\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"web\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_View\">\n    <xsd:attribute name=\"val\" type=\"ST_View\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Zoom\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fullPage\"/>\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"textFit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Zoom\">\n    <xsd:attribute name=\"val\" type=\"ST_Zoom\" use=\"optional\"/>\n    <xsd:attribute name=\"percent\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WritingStyle\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"vendorID\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"dllVersion\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"nlCheck\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"checkStyle\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"appName\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Proof\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clean\"/>\n      <xsd:enumeration value=\"dirty\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Proof\">\n    <xsd:attribute name=\"spelling\" type=\"ST_Proof\" use=\"optional\"/>\n    <xsd:attribute name=\"grammar\" type=\"ST_Proof\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocType\">\n    <xsd:attribute name=\"val\" type=\"ST_DocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocProtect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"readOnly\"/>\n      <xsd:enumeration value=\"comments\"/>\n      <xsd:enumeration value=\"trackedChanges\"/>\n      <xsd:enumeration value=\"forms\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Password\">\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_TransitionalPassword\">\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptSpinCount\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hash\" type=\"xsd:base64Binary\"/>\n    <xsd:attribute name=\"salt\" type=\"xsd:base64Binary\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_DocProtect\">\n    <xsd:attribute name=\"edit\" type=\"ST_DocProtect\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"enforcement\" type=\"s:ST_OnOff\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDocType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"catalog\"/>\n      <xsd:enumeration value=\"envelopes\"/>\n      <xsd:enumeration value=\"mailingLabels\"/>\n      <xsd:enumeration value=\"formLetters\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDocType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDataType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDest\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newDocument\"/>\n      <xsd:enumeration value=\"printer\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDest\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDest\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeOdsoFMDFieldType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"dbColumn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeOdsoFMDFieldType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeOdsoFMDFieldType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangesView\">\n    <xsd:attribute name=\"markup\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"comments\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"insDel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"inkAnnotations\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextDirection\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tb\"/>\n      <xsd:enumeration value=\"rl\"/>\n      <xsd:enumeration value=\"lr\"/>\n      <xsd:enumeration value=\"tbV\"/>\n      <xsd:enumeration value=\"rlV\"/>\n      <xsd:enumeration value=\"lrV\"/>\n      <xsd:enumeration value=\"btLr\"/>\n      <xsd:enumeration value=\"lrTb\"/>\n      <xsd:enumeration value=\"lrTbV\"/>\n      <xsd:enumeration value=\"tbLrV\"/>\n      <xsd:enumeration value=\"tbRl\"/>\n      <xsd:enumeration value=\"tbRlV\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextDirection\">\n    <xsd:attribute name=\"val\" type=\"ST_TextDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextAlignment\">\n    <xsd:attribute name=\"val\" type=\"ST_TextAlignment\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DisplacedByCustomXml\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"next\"/>\n      <xsd:enumeration value=\"prev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnnotationVMerge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cont\"/>\n      <xsd:enumeration value=\"rest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Markup\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellMergeTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"vMerge\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n        <xsd:attribute name=\"vMergeOrig\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MarkupRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookmarkRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_MarkupRange\">\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_BookmarkRange\">\n        <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MoveBookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Bookmark\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"initials\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeNumbering\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"original\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrEx\" type=\"CT_TblPrExBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPr\" type=\"CT_TcPrInner\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"trPr\" type=\"CT_TrPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGrid\" type=\"CT_TblGridBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPrBase\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"pPr\" type=\"CT_PPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_RPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RunTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:group ref=\"EG_ContentRunContent\"/>\n          <xsd:group ref=\"m:EG_OMathMathElements\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContentMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_PContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_ContentRunContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_PContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ContentRunContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_CellMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"cellIns\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellDel\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellMerge\" type=\"CT_CellMergeTrackChange\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RangeMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"bookmarkStart\" type=\"CT_Bookmark\"/>\n      <xsd:element name=\"bookmarkEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveFromRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveFromRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveToRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveToRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeStart\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"customXmlInsRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlInsRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlDelRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlDelRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveFromRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveFromRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveToRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveToRangeEnd\" type=\"CT_Markup\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_NumPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ilvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"between\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bar\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tabs\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TabStop\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextboxTightWrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"allLines\"/>\n      <xsd:enumeration value=\"firstAndLastLine\"/>\n      <xsd:enumeration value=\"firstLineOnly\"/>\n      <xsd:enumeration value=\"lastLineOnly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextboxTightWrap\">\n    <xsd:attribute name=\"val\" type=\"ST_TextboxTightWrap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepNext\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageBreakBefore\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"framePr\" type=\"CT_FramePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"widowControl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"numPr\" type=\"CT_NumPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressLineNumbers\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pBdr\" type=\"CT_PBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabs\" type=\"CT_Tabs\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressAutoHyphens\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wordWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"overflowPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"topLinePunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDE\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDN\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustRightInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacing\" type=\"CT_Spacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"ind\" type=\"CT_Ind\" minOccurs=\"0\"/>\n      <xsd:element name=\"contextualSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorIndents\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressOverlap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"jc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"textAlignment\" type=\"CT_TextAlignment\" minOccurs=\"0\"/>\n      <xsd:element name=\"textboxTightWrap\" type=\"CT_TextboxTightWrap\" minOccurs=\"0\"/>\n      <xsd:element name=\"outlineLvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrGeneral\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeid\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Object\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"control\" type=\"CT_Control\"/>\n        <xsd:element name=\"objectLink\" type=\"CT_ObjectLink\"/>\n        <xsd:element name=\"objectEmbed\" type=\"CT_ObjectEmbed\"/>\n        <xsd:element name=\"movie\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"dxaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"dyaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"movie\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectEmbed\">\n    <xsd:attribute name=\"drawAspect\" type=\"ST_ObjectDrawAspect\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldCodes\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ObjectLink\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_ObjectEmbed\">\n        <xsd:attribute name=\"updateMode\" type=\"ST_ObjectUpdateMode\" use=\"required\"/>\n        <xsd:attribute name=\"lockedField\" type=\"s:ST_OnOff\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"onCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"wp:anchor\" minOccurs=\"0\"/>\n      <xsd:element ref=\"wp:inline\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SimpleField\">\n    <xsd:sequence>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"instr\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FldCharType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"separate\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InfoTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"autoText\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFHelpTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"256\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFStatusTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"140\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"65\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"regular\"/>\n      <xsd:enumeration value=\"number\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"currentTime\"/>\n      <xsd:enumeration value=\"currentDate\"/>\n      <xsd:enumeration value=\"calculated\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FFTextType\">\n    <xsd:attribute name=\"val\" type=\"ST_FFTextType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFName\">\n    <xsd:attribute name=\"val\" type=\"ST_FFName\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FldChar\">\n    <xsd:choice>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ffData\" type=\"CT_FFData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fldCharType\" type=\"ST_FldCharType\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"docLocation\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"history\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFData\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FFName\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"enabled\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"calcOnExit\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"entryMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"exitMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"helpText\" type=\"CT_FFHelpText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"statusText\" type=\"CT_FFStatusText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"checkBox\" type=\"CT_FFCheckBox\"/>\n        <xsd:element name=\"ddList\" type=\"CT_FFDDList\"/>\n        <xsd:element name=\"textInput\" type=\"CT_FFTextInput\"/>\n      </xsd:choice>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFHelpText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFHelpTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFStatusText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFStatusTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFCheckBox\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"size\" type=\"CT_HpsMeasure\"/>\n        <xsd:element name=\"sizeAuto\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"default\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFDDList\">\n    <xsd:sequence>\n      <xsd:element name=\"result\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"listEntry\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFTextInput\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FFTextType\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxLength\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"format\" type=\"CT_String\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SectionMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nextPage\"/>\n      <xsd:enumeration value=\"nextColumn\"/>\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"evenPage\"/>\n      <xsd:enumeration value=\"oddPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SectType\">\n    <xsd:attribute name=\"val\" type=\"ST_SectionMark\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PaperSource\">\n    <xsd:attribute name=\"first\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"other\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumberFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"upperRoman\"/>\n      <xsd:enumeration value=\"lowerRoman\"/>\n      <xsd:enumeration value=\"upperLetter\"/>\n      <xsd:enumeration value=\"lowerLetter\"/>\n      <xsd:enumeration value=\"ordinal\"/>\n      <xsd:enumeration value=\"cardinalText\"/>\n      <xsd:enumeration value=\"ordinalText\"/>\n      <xsd:enumeration value=\"hex\"/>\n      <xsd:enumeration value=\"chicago\"/>\n      <xsd:enumeration value=\"ideographDigital\"/>\n      <xsd:enumeration value=\"japaneseCounting\"/>\n      <xsd:enumeration value=\"aiueo\"/>\n      <xsd:enumeration value=\"iroha\"/>\n      <xsd:enumeration value=\"decimalFullWidth\"/>\n      <xsd:enumeration value=\"decimalHalfWidth\"/>\n      <xsd:enumeration value=\"japaneseLegal\"/>\n      <xsd:enumeration value=\"japaneseDigitalTenThousand\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircle\"/>\n      <xsd:enumeration value=\"decimalFullWidth2\"/>\n      <xsd:enumeration value=\"aiueoFullWidth\"/>\n      <xsd:enumeration value=\"irohaFullWidth\"/>\n      <xsd:enumeration value=\"decimalZero\"/>\n      <xsd:enumeration value=\"bullet\"/>\n      <xsd:enumeration value=\"ganada\"/>\n      <xsd:enumeration value=\"chosung\"/>\n      <xsd:enumeration value=\"decimalEnclosedFullstop\"/>\n      <xsd:enumeration value=\"decimalEnclosedParen\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircleChinese\"/>\n      <xsd:enumeration value=\"ideographEnclosedCircle\"/>\n      <xsd:enumeration value=\"ideographTraditional\"/>\n      <xsd:enumeration value=\"ideographZodiac\"/>\n      <xsd:enumeration value=\"ideographZodiacTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCounting\"/>\n      <xsd:enumeration value=\"ideographLegalTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCountingThousand\"/>\n      <xsd:enumeration value=\"taiwaneseDigital\"/>\n      <xsd:enumeration value=\"chineseCounting\"/>\n      <xsd:enumeration value=\"chineseLegalSimplified\"/>\n      <xsd:enumeration value=\"chineseCountingThousand\"/>\n      <xsd:enumeration value=\"koreanDigital\"/>\n      <xsd:enumeration value=\"koreanCounting\"/>\n      <xsd:enumeration value=\"koreanLegal\"/>\n      <xsd:enumeration value=\"koreanDigital2\"/>\n      <xsd:enumeration value=\"vietnameseCounting\"/>\n      <xsd:enumeration value=\"russianLower\"/>\n      <xsd:enumeration value=\"russianUpper\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"numberInDash\"/>\n      <xsd:enumeration value=\"hebrew1\"/>\n      <xsd:enumeration value=\"hebrew2\"/>\n      <xsd:enumeration value=\"arabicAlpha\"/>\n      <xsd:enumeration value=\"arabicAbjad\"/>\n      <xsd:enumeration value=\"hindiVowels\"/>\n      <xsd:enumeration value=\"hindiConsonants\"/>\n      <xsd:enumeration value=\"hindiNumbers\"/>\n      <xsd:enumeration value=\"hindiCounting\"/>\n      <xsd:enumeration value=\"thaiLetters\"/>\n      <xsd:enumeration value=\"thaiNumbers\"/>\n      <xsd:enumeration value=\"thaiCounting\"/>\n      <xsd:enumeration value=\"bahtText\"/>\n      <xsd:enumeration value=\"dollarText\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageSz\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_PageOrientation\" use=\"optional\"/>\n    <xsd:attribute name=\"code\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMar\">\n    <xsd:attribute name=\"top\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"left\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"gutter\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageBorderZOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"front\"/>\n      <xsd:enumeration value=\"back\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderDisplay\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"allPages\"/>\n      <xsd:enumeration value=\"firstPage\"/>\n      <xsd:enumeration value=\"notFirstPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderOffset\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TopPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BottomPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zOrder\" type=\"ST_PageBorderZOrder\" use=\"optional\" default=\"front\"/>\n    <xsd:attribute name=\"display\" type=\"ST_PageBorderDisplay\" use=\"optional\"/>\n    <xsd:attribute name=\"offsetFrom\" type=\"ST_PageBorderOffset\" use=\"optional\" default=\"text\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Border\">\n        <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BottomPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:bottomLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:bottomRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TopPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:topLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:topRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ChapterSep\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"period\"/>\n      <xsd:enumeration value=\"colon\"/>\n      <xsd:enumeration value=\"emDash\"/>\n      <xsd:enumeration value=\"enDash\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineNumberRestart\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newPage\"/>\n      <xsd:enumeration value=\"newSection\"/>\n      <xsd:enumeration value=\"continuous\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineNumber\">\n    <xsd:attribute name=\"countBy\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"distance\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_LineNumberRestart\" use=\"optional\" default=\"newPage\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageNumber\">\n    <xsd:attribute name=\"fmt\" type=\"ST_NumberFormat\" use=\"optional\" default=\"decimal\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapStyle\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapSep\" type=\"ST_ChapterSep\" use=\"optional\" default=\"hyphen\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Column\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Columns\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"col\" type=\"CT_Column\" maxOccurs=\"45\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"equalWidth\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"720\"/>\n    <xsd:attribute name=\"num\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"sep\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VerticalJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"bottom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VerticalJc\">\n    <xsd:attribute name=\"val\" type=\"ST_VerticalJc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocGrid\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"lines\"/>\n      <xsd:enumeration value=\"linesAndChars\"/>\n      <xsd:enumeration value=\"snapToChars\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocGrid\">\n    <xsd:attribute name=\"type\" type=\"ST_DocGrid\"/>\n    <xsd:attribute name=\"linePitch\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"charSpace\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HdrFtr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"even\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"first\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FtnEdn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"separator\"/>\n      <xsd:enumeration value=\"continuationSeparator\"/>\n      <xsd:enumeration value=\"continuationNotice\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HdrFtrRef\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"type\" type=\"ST_HdrFtr\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_HdrFtrReferences\">\n    <xsd:choice>\n      <xsd:element name=\"headerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n      <xsd:element name=\"footerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_HdrFtr\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SectPrContents\">\n    <xsd:sequence>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_SectType\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgSz\" type=\"CT_PageSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgMar\" type=\"CT_PageMar\" minOccurs=\"0\"/>\n      <xsd:element name=\"paperSrc\" type=\"CT_PaperSource\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgBorders\" type=\"CT_PageBorders\" minOccurs=\"0\"/>\n      <xsd:element name=\"lnNumType\" type=\"CT_LineNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNumType\" type=\"CT_PageNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cols\" type=\"CT_Columns\" minOccurs=\"0\"/>\n      <xsd:element name=\"formProt\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"noEndnote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"titlePg\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rtlGutter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"docGrid\" type=\"CT_DocGrid\" minOccurs=\"0\"/>\n      <xsd:element name=\"printerSettings\" type=\"CT_Rel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_SectPrAttributes\">\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidSect\" type=\"ST_LongHexNumber\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_SectPrBase\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_HdrFtrReferences\" minOccurs=\"0\" maxOccurs=\"6\"/>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n      <xsd:element name=\"sectPrChange\" type=\"CT_SectPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BrType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"textWrapping\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BrClear\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Br\">\n    <xsd:attribute name=\"type\" type=\"ST_BrType\" use=\"optional\"/>\n    <xsd:attribute name=\"clear\" type=\"ST_BrClear\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PTabAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabRelativeTo\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"indent\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabLeader\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PTab\">\n    <xsd:attribute name=\"alignment\" type=\"ST_PTabAlignment\" use=\"required\"/>\n    <xsd:attribute name=\"relativeTo\" type=\"ST_PTabRelativeTo\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_PTabLeader\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sym\">\n    <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"char\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ProofErr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"spellStart\"/>\n      <xsd:enumeration value=\"spellEnd\"/>\n      <xsd:enumeration value=\"gramStart\"/>\n      <xsd:enumeration value=\"gramEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ProofErr\">\n    <xsd:attribute name=\"type\" type=\"ST_ProofErr\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdGrp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"everyone\"/>\n      <xsd:enumeration value=\"administrators\"/>\n      <xsd:enumeration value=\"contributors\"/>\n      <xsd:enumeration value=\"editors\"/>\n      <xsd:enumeration value=\"owners\"/>\n      <xsd:enumeration value=\"current\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perm\">\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PermStart\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Perm\">\n        <xsd:attribute name=\"edGrp\" type=\"ST_EdGrp\" use=\"optional\"/>\n        <xsd:attribute name=\"ed\" type=\"s:ST_String\" use=\"optional\"/>\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RunInnerContent\">\n    <xsd:choice>\n      <xsd:element name=\"br\" type=\"CT_Br\"/>\n      <xsd:element name=\"t\" type=\"CT_Text\"/>\n      <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      <xsd:element name=\"delText\" type=\"CT_Text\"/>\n      <xsd:element name=\"instrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"delInstrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"noBreakHyphen\" type=\"CT_Empty\"/>\n      <xsd:element name=\"softHyphen\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"annotationRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"separator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"continuationSeparator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"sym\" type=\"CT_Sym\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNum\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"cr\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"tab\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"object\" type=\"CT_Object\"/>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"fldChar\" type=\"CT_FldChar\"/>\n      <xsd:element name=\"ruby\" type=\"CT_Ruby\"/>\n      <xsd:element name=\"footnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"endnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"commentReference\" type=\"CT_Markup\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"ptab\" type=\"CT_PTab\" minOccurs=\"0\"/>\n      <xsd:element name=\"lastRenderedPageBreak\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RunInnerContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Hint\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"eastAsia\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Theme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"majorEastAsia\"/>\n      <xsd:enumeration value=\"majorBidi\"/>\n      <xsd:enumeration value=\"majorAscii\"/>\n      <xsd:enumeration value=\"majorHAnsi\"/>\n      <xsd:enumeration value=\"minorEastAsia\"/>\n      <xsd:enumeration value=\"minorBidi\"/>\n      <xsd:enumeration value=\"minorAscii\"/>\n      <xsd:enumeration value=\"minorHAnsi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:attribute name=\"hint\" type=\"ST_Hint\"/>\n    <xsd:attribute name=\"ascii\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hAnsi\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cs\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"asciiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"hAnsiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"eastAsiaTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"cstheme\" type=\"ST_Theme\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPrBase\">\n    <xsd:choice>\n      <xsd:element name=\"rStyle\" type=\"CT_String\"/>\n      <xsd:element name=\"rFonts\" type=\"CT_Fonts\"/>\n      <xsd:element name=\"b\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"bCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"i\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"iCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"caps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"smallCaps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"strike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"dstrike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"outline\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"shadow\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"emboss\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"imprint\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"noProof\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"vanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"webHidden\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\"/>\n      <xsd:element name=\"spacing\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"w\" type=\"CT_TextScale\"/>\n      <xsd:element name=\"kern\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"position\" type=\"CT_SignedHpsMeasure\"/>\n      <xsd:element name=\"sz\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"szCs\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Highlight\"/>\n      <xsd:element name=\"u\" type=\"CT_Underline\"/>\n      <xsd:element name=\"effect\" type=\"CT_TextEffect\"/>\n      <xsd:element name=\"bdr\" type=\"CT_Border\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\"/>\n      <xsd:element name=\"fitText\" type=\"CT_FitText\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignRun\"/>\n      <xsd:element name=\"rtl\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"cs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"em\" type=\"CT_Em\"/>\n      <xsd:element name=\"lang\" type=\"CT_Language\"/>\n      <xsd:element name=\"eastAsianLayout\" type=\"CT_EastAsianLayout\"/>\n      <xsd:element name=\"specVanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OnOff\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrContent\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_RPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrContent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_RPr\"/>\n      <xsd:element name=\"ins\" type=\"CT_MathCtrlIns\"/>\n      <xsd:element name=\"del\" type=\"CT_MathCtrlDel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_MathCtrlIns\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"del\" type=\"CT_RPrChange\" minOccurs=\"1\"/>\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathCtrlDel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_ParaRPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ParaRPrTrackChanges\">\n    <xsd:sequence>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AltChunk\">\n    <xsd:sequence>\n      <xsd:element name=\"altChunkPr\" type=\"CT_AltChunkPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AltChunkPr\">\n    <xsd:sequence>\n      <xsd:element name=\"matchSrc\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RubyAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributeLetter\"/>\n      <xsd:enumeration value=\"distributeSpace\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"rightVertical\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RubyAlign\">\n    <xsd:attribute name=\"val\" type=\"ST_RubyAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RubyPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyAlign\" type=\"CT_RubyAlign\"/>\n      <xsd:element name=\"hps\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsRaise\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsBaseText\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\"/>\n      <xsd:element name=\"dirty\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RubyContent\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RubyContent\">\n    <xsd:group ref=\"EG_RubyContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ruby\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyPr\" type=\"CT_RubyPr\"/>\n      <xsd:element name=\"rt\" type=\"CT_RubyContent\"/>\n      <xsd:element name=\"rubyBase\" type=\"CT_RubyContent\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Lock\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sdtLocked\"/>\n      <xsd:enumeration value=\"contentLocked\"/>\n      <xsd:enumeration value=\"unlocked\"/>\n      <xsd:enumeration value=\"sdtContentLocked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attribute name=\"val\" type=\"ST_Lock\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtListItem\">\n    <xsd:attribute name=\"displayText\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"value\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SdtDateMappingType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"dateTime\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtDateMappingType\">\n    <xsd:attribute name=\"val\" type=\"ST_SdtDateMappingType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalendarType\">\n    <xsd:attribute name=\"val\" type=\"s:ST_CalendarType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDate\">\n    <xsd:sequence>\n      <xsd:element name=\"dateFormat\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"storeMappedDataAs\" type=\"CT_SdtDateMappingType\" minOccurs=\"0\"/>\n      <xsd:element name=\"calendar\" type=\"CT_CalendarType\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullDate\" type=\"ST_DateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtComboBox\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartGallery\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartCategory\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartUnique\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDropDownList\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"docPart\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtText\">\n    <xsd:attribute name=\"multiLine\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:attribute name=\"prefixMappings\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"storeItemID\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"alias\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tag\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"id\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lock\" type=\"CT_Lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"placeholder\" type=\"CT_Placeholder\" minOccurs=\"0\"/>\n      <xsd:element name=\"temporary\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showingPlcHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"equation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comboBox\" type=\"CT_SdtComboBox\"/>\n        <xsd:element name=\"date\" type=\"CT_SdtDate\"/>\n        <xsd:element name=\"docPartObj\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"docPartList\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"dropDownList\" type=\"CT_SdtDropDownList\"/>\n        <xsd:element name=\"picture\" type=\"CT_Empty\"/>\n        <xsd:element name=\"richText\" type=\"CT_Empty\"/>\n        <xsd:element name=\"text\" type=\"CT_SdtText\"/>\n        <xsd:element name=\"citation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"group\" type=\"CT_Empty\"/>\n        <xsd:element name=\"bibliography\" type=\"CT_Empty\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtEndPr\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRunContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:element name=\"dir\" type=\"CT_DirContentRun\"/>\n      <xsd:element name=\"bdo\" type=\"CT_BdoContentRun\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DirContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BdoContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ltr\"/>\n      <xsd:enumeration value=\"rtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentBlockContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlBlock\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtBlock\"/>\n      <xsd:element name=\"p\" type=\"CT_P\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tbl\" type=\"CT_Tbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentBlock\">\n    <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRowContent\">\n    <xsd:choice>\n      <xsd:element name=\"tr\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRow\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRow\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentRow\">\n    <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentCellContent\">\n    <xsd:choice>\n      <xsd:element name=\"tc\" type=\"CT_Tc\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlCell\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtCell\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentCell\">\n    <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentBlock\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRun\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRun\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtCell\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentCell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRow\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRow\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Attr\">\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRun\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagRun\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"placeholder\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRow\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:sequence>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContent\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentRunContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n      <xsd:element name=\"subDoc\" type=\"CT_Rel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_P\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidP\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidRDefault\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"pct\"/>\n      <xsd:enumeration value=\"dxa\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Height\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MeasurementOrPercent\">\n    <xsd:union memberTypes=\"ST_DecimalNumberOrPercent s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblWidth\">\n    <xsd:attribute name=\"w\" type=\"ST_MeasurementOrPercent\"/>\n    <xsd:attribute name=\"type\" type=\"ST_TblWidth\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridCol\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridBase\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TblGridCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGrid\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblGridBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGridChange\" type=\"CT_TblGridChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Merge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continue\"/>\n      <xsd:enumeration value=\"restart\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpan\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hMerge\" type=\"CT_HMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"vMerge\" type=\"CT_VMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcBorders\" type=\"CT_TcBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"noWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcMar\" type=\"CT_TcMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcFitText\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrInner\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPrChange\" type=\"CT_TcPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrInner\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrBase\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_CellMarkupElements\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tc\">\n    <xsd:sequence>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Cnf\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:length value=\"12\"/>\n      <xsd:pattern value=\"[01]*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cnf\">\n    <xsd:attribute name=\"val\" type=\"ST_Cnf\"/>\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowLastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowLastColumn\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrBase\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridBefore\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridAfter\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"wBefore\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wAfter\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cantSplit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"trHeight\" type=\"CT_Height\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"trPrChange\" type=\"CT_TrPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPrEx\" type=\"CT_TblPrEx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidTr\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblLayoutType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"autofit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblLayoutType\">\n    <xsd:attribute name=\"type\" type=\"ST_TblLayoutType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblOverlap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"overlap\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblOverlap\">\n    <xsd:attribute name=\"val\" type=\"ST_TblOverlap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPPr\">\n    <xsd:attribute name=\"leftFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"rightFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"topFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"bottomFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"vertAnchor\" type=\"ST_VAnchor\"/>\n    <xsd:attribute name=\"horzAnchor\" type=\"ST_HAnchor\"/>\n    <xsd:attribute name=\"tblpXSpec\" type=\"s:ST_XAlign\"/>\n    <xsd:attribute name=\"tblpX\" type=\"ST_SignedTwipsMeasure\"/>\n    <xsd:attribute name=\"tblpYSpec\" type=\"s:ST_YAlign\"/>\n    <xsd:attribute name=\"tblpY\" type=\"ST_SignedTwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblCellMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblpPr\" type=\"CT_TblPPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblOverlap\" type=\"CT_TblOverlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bidiVisual\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleRowBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleColBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCaption\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblDescription\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrChange\" type=\"CT_TblPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrEx\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrExBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrExChange\" type=\"CT_TblPrExChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tbl\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPr\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TblGrid\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblLook\">\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FtnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pageBottom\"/>\n      <xsd:enumeration value=\"beneathText\"/>\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FtnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_FtnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EdnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_EdnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"val\" type=\"ST_NumberFormat\" use=\"required\"/>\n    <xsd:attribute name=\"format\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RestartNumber\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"eachSect\"/>\n      <xsd:enumeration value=\"eachPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumRestart\">\n    <xsd:attribute name=\"val\" type=\"ST_RestartNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnRef\">\n    <xsd:attribute name=\"customMarkFollows\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnSepRef\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdn\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_FtnEdn\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FtnEdnNumProps\">\n    <xsd:sequence>\n      <xsd:element name=\"numStart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numRestart\" type=\"CT_NumRestart\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FtnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_FtnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_EdnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_FtnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"footnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_EdnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"endnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RecipientData\">\n    <xsd:sequence>\n      <xsd:element name=\"active\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"uniqueTag\" type=\"CT_Base64Binary\" minOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Base64Binary\">\n    <xsd:attribute name=\"val\" type=\"xsd:base64Binary\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Recipients\">\n    <xsd:sequence>\n      <xsd:element name=\"recipientData\" type=\"CT_RecipientData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"recipients\" type=\"CT_Recipients\"/>\n  <xsd:complexType name=\"CT_OdsoFieldMapData\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_MailMergeOdsoFMDFieldType\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mappedName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"dynamicAddress\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"database\"/>\n      <xsd:enumeration value=\"addressBook\"/>\n      <xsd:enumeration value=\"document1\"/>\n      <xsd:enumeration value=\"document2\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"native\"/>\n      <xsd:enumeration value=\"legacy\"/>\n      <xsd:enumeration value=\"master\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeSourceType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MailMergeSourceType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Odso\">\n    <xsd:sequence>\n      <xsd:element name=\"udl\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"table\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"src\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"colDelim\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_MailMergeSourceType\" minOccurs=\"0\"/>\n      <xsd:element name=\"fHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"fieldMapData\" type=\"CT_OdsoFieldMapData\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"recipientData\" type=\"CT_Rel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MailMerge\">\n    <xsd:sequence>\n      <xsd:element name=\"mainDocumentType\" type=\"CT_MailMergeDocType\" minOccurs=\"1\"/>\n      <xsd:element name=\"linkToQuery\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataType\" type=\"CT_MailMergeDataType\" minOccurs=\"1\"/>\n      <xsd:element name=\"connectString\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"query\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"headerSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressBlankLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"destination\" type=\"CT_MailMergeDest\" minOccurs=\"0\"/>\n      <xsd:element name=\"addressFieldName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailSubject\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailAsAttachment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"viewMergedData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeRecord\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"checkErrors\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"odso\" type=\"CT_Odso\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSz\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TargetScreenSz\">\n    <xsd:attribute name=\"val\" type=\"ST_TargetScreenSz\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Compat\">\n    <xsd:sequence>\n      <xsd:element name=\"useSingleBorderforContiguousCells\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpJustification\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noTabHangInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLeading\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spaceForUL\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noColumnBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"balanceSingleByteDoubleByteWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noExtraLineSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotLeaveBackslashAlone\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ulTrailSpace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotExpandShiftReturn\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacingInWholePoints\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lineWrapLikeWord6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printBodyTextBeforeHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printColBlack\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpSpaceWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showBreaksInFrames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subFontBySize\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressBottomSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpacingAtTopOfPage\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacingWP\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpBfAfterPgBrk\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"swapBordersFacingPages\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"convMailMergeEsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"truncateFontHeightsLikeWP6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mwSmallCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"usePrinterMetrics\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressParagraphBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wrapTrailSpaces\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shapeLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignTablesRowByRow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forgetLastTabAlignment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustLineHeightInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceLikeWord95\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noSpaceRaiseLower\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseHTMLParagraphAutoSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutRawTableWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutTableRowsApart\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord97LineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakWrappedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSnapToGridInCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"selectFldWithFirstOrLastChar\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"applyBreakingRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotWrapTextWithPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseEastAsianBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord2002TableStyleRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"growAutofit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useFELayout\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useNormalStyleForList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseIndentAsNumberingTabStop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAltKinsokuLineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowSpaceOfSameStyleInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressIndentation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutofitConstrainedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autofitToFirstFixedWidthCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"underlineTabInNumList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHangulFixedWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"splitPgBreakAndParaMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignCellWithSp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakConstrainedForcedTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignInTxbx\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAnsiKerningPairs\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"cachedColBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"compatSetting\" type=\"CT_CompatSetting\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CompatSetting\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVar\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVars\">\n    <xsd:sequence>\n      <xsd:element name=\"docVar\" type=\"CT_DocVar\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocRsids\">\n    <xsd:sequence>\n      <xsd:element name=\"rsidRoot\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CharacterSpacing\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doNotCompress\"/>\n      <xsd:enumeration value=\"compressPunctuation\"/>\n      <xsd:enumeration value=\"compressPunctuationAndJapaneseKana\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CharacterSpacing\">\n    <xsd:attribute name=\"val\" type=\"ST_CharacterSpacing\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SaveThroughXslt\">\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"solutionID\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"rPrDefault\" type=\"CT_RPrDefault\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPrDefault\" type=\"CT_PPrDefault\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WmlColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorSchemeMapping\">\n    <xsd:attribute name=\"bg1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"hyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"followedHyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReadingModeInkLockDown\">\n    <xsd:attribute name=\"actualPg\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"w\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"fontSz\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WriteProtection\">\n    <xsd:attribute name=\"recommended\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Settings\">\n    <xsd:sequence>\n      <xsd:element name=\"writeProtection\" type=\"CT_WriteProtection\" minOccurs=\"0\"/>\n      <xsd:element name=\"view\" type=\"CT_View\" minOccurs=\"0\"/>\n      <xsd:element name=\"zoom\" type=\"CT_Zoom\" minOccurs=\"0\"/>\n      <xsd:element name=\"removePersonalInformation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"removeDateAndTime\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDisplayPageBoundaries\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayBackgroundShape\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printPostScriptOverText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFractionalCharacterWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedTrueTypeFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedSystemFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSubsetFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorMargins\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignBordersAndEdges\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundFooter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"gutterAtTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideSpellingErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideGrammaticalErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeWritingStyle\" type=\"CT_WritingStyle\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"proofState\" type=\"CT_Proof\" minOccurs=\"0\"/>\n      <xsd:element name=\"formsDesign\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"attachedTemplate\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkStyles\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneFormatFilter\" type=\"CT_StylePaneFilter\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneSortMethod\" type=\"CT_StyleSort\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentType\" type=\"CT_DocType\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailMerge\" type=\"CT_MailMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"revisionView\" type=\"CT_TrackChangesView\" minOccurs=\"0\"/>\n      <xsd:element name=\"trackRevisions\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackMoves\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackFormatting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentProtection\" type=\"CT_DocProtect\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoFormatOverride\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockTheme\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockQFSet\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTabStop\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoHyphenation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"consecutiveHyphenLimit\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hyphenationZone\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotHyphenateCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showEnvelope\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"summaryLength\" type=\"CT_DecimalNumberOrPrecent\" minOccurs=\"0\"/>\n      <xsd:element name=\"clickAndTypeStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTableStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"evenAndOddHeaders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldRevPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrintingSheets\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHorizontalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayVerticalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseMarginsForDrawingGridOrigin\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotShadeFormData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noPunctuationKerning\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"characterSpacingControl\" type=\"CT_CharacterSpacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"printTwoOnOne\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strictFirstAndLastChars\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksAfter\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksBefore\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"savePreviewPicture\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotValidateAgainstSchema\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ignoreMixedContent\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysShowPlaceholderText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDemarcateInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveXmlDataOnly\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useXSLTWhenSaving\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveThroughXslt\" type=\"CT_SaveThroughXslt\" minOccurs=\"0\"/>\n      <xsd:element name=\"showXMLTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysMergeEmptyNamespace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"updateFields\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hdrShapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"compat\" type=\"CT_Compat\" minOccurs=\"0\"/>\n      <xsd:element name=\"docVars\" type=\"CT_DocVars\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsids\" type=\"CT_DocRsids\" minOccurs=\"0\"/>\n      <xsd:element ref=\"m:mathPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attachedSchema\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"themeFontLang\" type=\"CT_Language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrSchemeMapping\" type=\"CT_ColorSchemeMapping\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotIncludeSubdocsInStats\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutoCompressPictures\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forceUpgrade\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"captions\" type=\"CT_Captions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"readModeInkLockDown\" type=\"CT_ReadingModeInkLockDown\" minOccurs=\"0\"/>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"sl:schemaLibrary\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotEmbedSmartTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"decimalSymbol\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"listSeparator\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleSort\">\n    <xsd:attribute name=\"val\" type=\"ST_StyleSort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StylePaneFilter\">\n    <xsd:attribute name=\"allStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"customStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"latentStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"stylesInUse\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"headingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"numberingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"tableStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnRuns\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnParagraphs\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnNumbering\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnTables\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"clearFormatting\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"top3HeadingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"visibleStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"alternateStyleNames\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleSort\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"name\"/>\n      <xsd:enumeration value=\"priority\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"font\"/>\n      <xsd:enumeration value=\"basedOn\"/>\n      <xsd:enumeration value=\"type\"/>\n      <xsd:enumeration value=\"0000\"/>\n      <xsd:enumeration value=\"0001\"/>\n      <xsd:enumeration value=\"0002\"/>\n      <xsd:enumeration value=\"0003\"/>\n      <xsd:enumeration value=\"0004\"/>\n      <xsd:enumeration value=\"0005\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\"/>\n      <xsd:element name=\"divs\" type=\"CT_Divs\" minOccurs=\"0\"/>\n      <xsd:element name=\"encoding\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"optimizeForBrowser\" type=\"CT_OptimizeForBrowser\" minOccurs=\"0\"/>\n      <xsd:element name=\"relyOnVML\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowPNG\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotRelyOnCSS\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSaveAsSingleFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotOrganizeInFolder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseLongFileNames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pixelsPerInch\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"targetScreenSz\" type=\"CT_TargetScreenSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSmartTagsAsXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameScrollbar\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameScrollbar\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameScrollbar\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptimizeForBrowser\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_OnOff\">\n        <xsd:attribute name=\"target\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frame\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"longDesc\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"sourceFileName\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"marW\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"marH\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"scrollbar\" type=\"CT_FrameScrollbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"noResizeAllowed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkedToFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameLayout\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rows\"/>\n      <xsd:enumeration value=\"cols\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameLayout\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameLayout\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FramesetSplitbar\">\n    <xsd:sequence>\n      <xsd:element name=\"w\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBorder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"flatBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frameset\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"framesetSplitbar\" type=\"CT_FramesetSplitbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"frameLayout\" type=\"CT_FrameLayout\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xsd:element name=\"frame\" type=\"CT_Frame\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumPicBullet\">\n    <xsd:choice>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"numPicBulletId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LevelSuffix\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tab\"/>\n      <xsd:enumeration value=\"space\"/>\n      <xsd:enumeration value=\"nothing\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LevelSuffix\">\n    <xsd:attribute name=\"val\" type=\"ST_LevelSuffix\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"null\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LvlLegacy\">\n    <xsd:attribute name=\"legacy\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"legacySpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"legacyIndent\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlRestart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"isLgl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suff\" type=\"CT_LevelSuffix\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlText\" type=\"CT_LevelText\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlPicBulletId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"legacy\" type=\"CT_LvlLegacy\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlJc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n    <xsd:attribute name=\"tplc\" type=\"ST_LongHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"tentative\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MultiLevelType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"singleLevel\"/>\n      <xsd:enumeration value=\"multilevel\"/>\n      <xsd:enumeration value=\"hybridMultilevel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MultiLevelType\">\n    <xsd:attribute name=\"val\" type=\"ST_MultiLevelType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbstractNum\">\n    <xsd:sequence>\n      <xsd:element name=\"nsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"multiLevelType\" type=\"CT_MultiLevelType\" minOccurs=\"0\"/>\n      <xsd:element name=\"tmpl\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"numStyleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"abstractNumId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumLvl\">\n    <xsd:sequence>\n      <xsd:element name=\"startOverride\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Num\">\n    <xsd:sequence>\n      <xsd:element name=\"abstractNumId\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"lvlOverride\" type=\"CT_NumLvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Numbering\">\n    <xsd:sequence>\n      <xsd:element name=\"numPicBullet\" type=\"CT_NumPicBullet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"abstractNum\" type=\"CT_AbstractNum\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"num\" type=\"CT_Num\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"numIdMacAtCleanup\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblStyleOverrideType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"firstRow\"/>\n      <xsd:enumeration value=\"lastRow\"/>\n      <xsd:enumeration value=\"firstCol\"/>\n      <xsd:enumeration value=\"lastCol\"/>\n      <xsd:enumeration value=\"band1Vert\"/>\n      <xsd:enumeration value=\"band2Vert\"/>\n      <xsd:enumeration value=\"band1Horz\"/>\n      <xsd:enumeration value=\"band2Horz\"/>\n      <xsd:enumeration value=\"neCell\"/>\n      <xsd:enumeration value=\"nwCell\"/>\n      <xsd:enumeration value=\"seCell\"/>\n      <xsd:enumeration value=\"swCell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblStylePr\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_TblStyleOverrideType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"table\"/>\n      <xsd:enumeration value=\"numbering\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"aliases\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"basedOn\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"next\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"link\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoRedefine\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"uiPriority\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"semiHidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"unhideWhenUsed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"qFormat\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"locked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personal\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalCompose\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalReply\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStylePr\" type=\"CT_TblStylePr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_StyleType\" use=\"optional\"/>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"default\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"customStyle\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LsdException\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"uiPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"semiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"unhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"qFormat\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LatentStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"lsdException\" type=\"CT_LsdException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"defLockedState\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUIPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"defSemiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUnhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defQFormat\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"count\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Styles\">\n    <xsd:sequence>\n      <xsd:element name=\"docDefaults\" type=\"CT_DocDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"latentStyles\" type=\"CT_LatentStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Panose\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Panose\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decorative\"/>\n      <xsd:enumeration value=\"modern\"/>\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"swiss\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pitch\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"variable\"/>\n      <xsd:enumeration value=\"default\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pitch\">\n    <xsd:attribute name=\"val\" type=\"ST_Pitch\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSig\">\n    <xsd:attribute name=\"usb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb2\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb3\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontRel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"fontKey\" type=\"s:ST_Guid\"/>\n        <xsd:attribute name=\"subsetted\" type=\"s:ST_OnOff\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:sequence>\n      <xsd:element name=\"altName\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"panose1\" type=\"CT_Panose\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_Charset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notTrueType\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pitch\" type=\"CT_Pitch\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sig\" type=\"CT_FontSig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedRegular\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBold\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBoldItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontsList\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DivBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Div\">\n    <xsd:sequence>\n      <xsd:element name=\"blockQuote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bodyDiv\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"marLeft\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marRight\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marTop\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marBottom\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"divBdr\" type=\"CT_DivBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"divsChild\" type=\"CT_Divs\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Divs\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"div\" type=\"CT_Div\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\"/>\n  <xsd:group name=\"EG_MathContent\">\n    <xsd:choice>\n      <xsd:element ref=\"m:oMathPara\"/>\n      <xsd:element ref=\"m:oMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelChunkElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_BlockLevelChunkElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"altChunk\" type=\"CT_AltChunk\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RunLevelElts\">\n    <xsd:choice>\n      <xsd:element name=\"proofErr\" minOccurs=\"0\" type=\"CT_ProofErr\"/>\n      <xsd:element name=\"permStart\" minOccurs=\"0\" type=\"CT_PermStart\"/>\n      <xsd:element name=\"permEnd\" minOccurs=\"0\" type=\"CT_Perm\"/>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ins\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_RunTrackChange\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_RunTrackChange\"/>\n      <xsd:group ref=\"EG_MathContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Body\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sectPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SectPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n        minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Footnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"footnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"footnotes\" type=\"CT_Footnotes\"/>\n  <xsd:complexType name=\"CT_Endnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"endnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"endnotes\" type=\"CT_Endnotes\"/>\n  <xsd:element name=\"hdr\" type=\"CT_HdrFtr\"/>\n  <xsd:element name=\"ftr\" type=\"CT_HdrFtr\"/>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceuri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ThemeColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"background1\"/>\n      <xsd:enumeration value=\"text1\"/>\n      <xsd:enumeration value=\"background2\"/>\n      <xsd:enumeration value=\"text2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DocPartBehavior\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"pg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartBehavior\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartBehavior\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartBehaviors\">\n    <xsd:choice>\n      <xsd:element name=\"behavior\" type=\"CT_DocPartBehavior\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"autoExp\"/>\n      <xsd:enumeration value=\"toolbar\"/>\n      <xsd:enumeration value=\"speller\"/>\n      <xsd:enumeration value=\"formFld\"/>\n      <xsd:enumeration value=\"bbPlcHdr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartTypes\">\n    <xsd:choice>\n      <xsd:element name=\"type\" type=\"CT_DocPartType\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"all\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartGallery\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"placeholder\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"docParts\"/>\n      <xsd:enumeration value=\"coverPg\"/>\n      <xsd:enumeration value=\"eq\"/>\n      <xsd:enumeration value=\"ftrs\"/>\n      <xsd:enumeration value=\"hdrs\"/>\n      <xsd:enumeration value=\"pgNum\"/>\n      <xsd:enumeration value=\"tbls\"/>\n      <xsd:enumeration value=\"watermarks\"/>\n      <xsd:enumeration value=\"autoTxt\"/>\n      <xsd:enumeration value=\"txtBox\"/>\n      <xsd:enumeration value=\"pgNumT\"/>\n      <xsd:enumeration value=\"pgNumB\"/>\n      <xsd:enumeration value=\"pgNumMargins\"/>\n      <xsd:enumeration value=\"tblOfContents\"/>\n      <xsd:enumeration value=\"bib\"/>\n      <xsd:enumeration value=\"custQuickParts\"/>\n      <xsd:enumeration value=\"custCoverPg\"/>\n      <xsd:enumeration value=\"custEq\"/>\n      <xsd:enumeration value=\"custFtrs\"/>\n      <xsd:enumeration value=\"custHdrs\"/>\n      <xsd:enumeration value=\"custPgNum\"/>\n      <xsd:enumeration value=\"custTbls\"/>\n      <xsd:enumeration value=\"custWatermarks\"/>\n      <xsd:enumeration value=\"custAutoTxt\"/>\n      <xsd:enumeration value=\"custTxtBox\"/>\n      <xsd:enumeration value=\"custPgNumT\"/>\n      <xsd:enumeration value=\"custPgNumB\"/>\n      <xsd:enumeration value=\"custPgNumMargins\"/>\n      <xsd:enumeration value=\"custTblOfContents\"/>\n      <xsd:enumeration value=\"custBib\"/>\n      <xsd:enumeration value=\"custom1\"/>\n      <xsd:enumeration value=\"custom2\"/>\n      <xsd:enumeration value=\"custom3\"/>\n      <xsd:enumeration value=\"custom4\"/>\n      <xsd:enumeration value=\"custom5\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartGallery\">\n    <xsd:attribute name=\"val\" type=\"ST_DocPartGallery\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartCategory\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gallery\" type=\"CT_DocPartGallery\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"decorated\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartPr\">\n    <xsd:all>\n      <xsd:element name=\"name\" type=\"CT_DocPartName\" minOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"category\" type=\"CT_DocPartCategory\" minOccurs=\"0\"/>\n      <xsd:element name=\"types\" type=\"CT_DocPartTypes\" minOccurs=\"0\"/>\n      <xsd:element name=\"behaviors\" type=\"CT_DocPartBehaviors\" minOccurs=\"0\"/>\n      <xsd:element name=\"description\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"guid\" type=\"CT_Guid\" minOccurs=\"0\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartPr\" type=\"CT_DocPartPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartBody\" type=\"CT_Body\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocParts\">\n    <xsd:choice>\n      <xsd:element name=\"docPart\" type=\"CT_DocPart\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:element name=\"settings\" type=\"CT_Settings\"/>\n  <xsd:element name=\"webSettings\" type=\"CT_WebSettings\"/>\n  <xsd:element name=\"fonts\" type=\"CT_FontsList\"/>\n  <xsd:element name=\"numbering\" type=\"CT_Numbering\"/>\n  <xsd:element name=\"styles\" type=\"CT_Styles\"/>\n  <xsd:simpleType name=\"ST_CaptionPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"above\"/>\n      <xsd:enumeration value=\"below\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Caption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_CaptionPos\" use=\"optional\"/>\n    <xsd:attribute name=\"chapNum\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"heading\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"noLabel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"numFmt\" type=\"ST_NumberFormat\" use=\"optional\"/>\n    <xsd:attribute name=\"sep\" type=\"ST_ChapterSep\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaptions\">\n    <xsd:sequence>\n      <xsd:element name=\"autoCaption\" type=\"CT_AutoCaption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Captions\">\n    <xsd:sequence>\n      <xsd:element name=\"caption\" type=\"CT_Caption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"autoCaptions\" type=\"CT_AutoCaptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocumentBase\">\n    <xsd:sequence>\n      <xsd:element name=\"background\" type=\"CT_Background\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Document\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"body\" type=\"CT_Body\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n        <xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlossaryDocument\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"docParts\" type=\"CT_DocParts\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:element name=\"document\" type=\"CT_Document\"/>\n  <xsd:element name=\"glossaryDocument\" type=\"CT_GlossaryDocument\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd",
    "content": "<?xml version='1.0'?>\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xs:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xs:element name=\"Types\" type=\"CT_Types\"/>\n  <xs:element name=\"Default\" type=\"CT_Default\"/>\n  <xs:element name=\"Override\" type=\"CT_Override\"/>\n\n  <xs:complexType name=\"CT_Types\">\n    <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element ref=\"Default\"/>\n      <xs:element ref=\"Override\"/>\n    </xs:choice>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Default\">\n    <xs:attribute name=\"Extension\" type=\"ST_Extension\" use=\"required\"/>\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Override\">\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n    <xs:attribute name=\"PartName\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:simpleType name=\"ST_ContentType\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))/((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))((\\s+)*;(\\s+)*(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))=((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+)|(&quot;(([\\p{IsLatin-1Supplement}\\p{IsBasicLatin}-[\\p{Cc}&#127;&quot;\\n\\r]]|(\\s+))|(\\\\[\\p{IsBasicLatin}]))*&quot;))))*)\"\n      />\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:simpleType name=\"ST_Extension\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"([!$&amp;'\\(\\)\\*\\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\\-_~])+\"/>\n    </xs:restriction>\n  </xs:simpleType>\n</xs:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:dcterms=\"http://purl.org/dc/terms/\" elementFormDefault=\"qualified\" blockDefault=\"#all\">\n\n  <xs:import namespace=\"http://purl.org/dc/elements/1.1/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd\"/>\n  <xs:import namespace=\"http://purl.org/dc/terms/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd\"/>\n  <xs:import id=\"xml\" namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n\n  <xs:element name=\"coreProperties\" type=\"CT_CoreProperties\"/>\n\n  <xs:complexType name=\"CT_CoreProperties\">\n    <xs:all>\n      <xs:element name=\"category\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"contentStatus\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dcterms:created\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:creator\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:description\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:identifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"keywords\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Keywords\"/>\n      <xs:element ref=\"dc:language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"lastModifiedBy\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"lastPrinted\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:dateTime\"/>\n      <xs:element ref=\"dcterms:modified\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"revision\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dc:subject\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"version\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n    </xs:all>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keywords\" mixed=\"true\">\n    <xs:sequence>\n      <xs:element name=\"value\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Keyword\"/>\n    </xs:sequence>\n    <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keyword\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"SignatureTime\" type=\"CT_SignatureTime\"/>\n  <xsd:element name=\"RelationshipReference\" type=\"CT_RelationshipReference\"/>\n  <xsd:element name=\"RelationshipsGroupReference\" type=\"CT_RelationshipsGroupReference\"/>\n\n  <xsd:complexType name=\"CT_SignatureTime\">\n    <xsd:sequence>\n      <xsd:element name=\"Format\" type=\"ST_Format\"/>\n      <xsd:element name=\"Value\" type=\"ST_Value\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceId\" type=\"xsd:string\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipsGroupReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceType\" type=\"xsd:anyURI\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_Format\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n\n  <xsd:simpleType name=\"ST_Value\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\\.[0-9])(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"Relationships\" type=\"CT_Relationships\"/>\n  <xsd:element name=\"Relationship\" type=\"CT_Relationship\"/>\n\n  <xsd:complexType name=\"CT_Relationships\">\n    <xsd:sequence>\n      <xsd:element ref=\"Relationship\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_Relationship\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"TargetMode\" type=\"ST_TargetMode\" use=\"optional\"/>\n        <xsd:attribute name=\"Target\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Type\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Id\" type=\"xsd:ID\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_TargetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"External\"/>\n      <xsd:enumeration value=\"Internal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/mce/mc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\tattributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\"\n\ttargetNamespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--\n    This XSD is a modified version of the one found at:\n    https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd\n\n    This XSD has 2 objectives:\n\n        1. round tripping @mc:Ignorable\n\n\t\t\t<w:document\n\t\t\t            xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t            xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t\t\t            mc:Ignorable=\"w14 w15 wp14\">\n\n        2. enabling AlternateContent to be manipulated in certain elements\n           (in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)\n\n\t\tSee further ECMA-376, 4th Edition, Office Open XML File Formats\n\t\tPart 3 : Markup Compatibility and Extensibility\n   -->\n\n  <!--  Objective 1 -->\n  <xsd:attribute name=\"Ignorable\" type=\"xsd:string\" />\n\n  <!--  Objective 2 -->\n\t<xsd:attribute name=\"MustUnderstand\" type=\"xsd:string\"  />\n\t<xsd:attribute name=\"ProcessContent\" type=\"xsd:string\"  />\n\n<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a\nFallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice\nelements. -->\n\t<xsd:element name=\"AlternateContent\">\n\t\t<xsd:complexType>\n\t\t\t<xsd:sequence>\n\t\t\t\t<xsd:element name=\"Choice\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute name=\"Requires\" type=\"xsd:string\" use=\"required\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t\t<xsd:element name=\"Fallback\" minOccurs=\"0\" maxOccurs=\"1\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t</xsd:sequence>\n\t\t\t<!-- AlternateContent elements might include the attributes Ignorable,\n\t\t\t\tMustUnderstand and ProcessContent described in this Part of ECMA-376. These\n\t\t\t\tattributes’ qualified names shall be prefixed when associated with an AlternateContent\n\t\t\t\telement. -->\n\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t</xsd:complexType>\n\t</xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns=\"http://schemas.microsoft.com/office/word/2010/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2010/wordml\">\n   <!-- <xsd:import id=\"rel\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" schemaLocation=\"orel.xsd\"/> -->\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <!-- <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartbasetypes.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartsplineproperties.xsd\"/> -->\n   <xsd:complexType name=\"CT_LongHexNumber\">\n     <xsd:attribute name=\"val\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_OnOff\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"true\"/>\n       <xsd:enumeration value=\"false\"/>\n       <xsd:enumeration value=\"0\"/>\n       <xsd:enumeration value=\"1\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_OnOff\">\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\"/>\n   </xsd:complexType>\n   <xsd:element name=\"docId\" type=\"CT_LongHexNumber\"/>\n   <xsd:element name=\"conflictMode\" type=\"CT_OnOff\"/>\n   <xsd:attributeGroup name=\"AG_Parids\">\n     <xsd:attribute name=\"paraId\" type=\"w:ST_LongHexNumber\"/>\n     <xsd:attribute name=\"textId\" type=\"w:ST_LongHexNumber\"/>\n   </xsd:attributeGroup>\n   <xsd:attribute name=\"anchorId\" type=\"w:ST_LongHexNumber\"/>\n   <xsd:attribute name=\"noSpellErr\" type=\"ST_OnOff\"/>\n   <xsd:element name=\"customXmlConflictInsRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictInsRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:element name=\"customXmlConflictDelRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictDelRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:group name=\"EG_RunLevelConflicts\">\n     <xsd:sequence>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:group name=\"EG_Conflicts\">\n     <xsd:choice>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Percentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_Percentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositivePercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_SchemeColorVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"bg1\"/>\n       <xsd:enumeration value=\"tx1\"/>\n       <xsd:enumeration value=\"bg2\"/>\n       <xsd:enumeration value=\"tx2\"/>\n       <xsd:enumeration value=\"accent1\"/>\n       <xsd:enumeration value=\"accent2\"/>\n       <xsd:enumeration value=\"accent3\"/>\n       <xsd:enumeration value=\"accent4\"/>\n       <xsd:enumeration value=\"accent5\"/>\n       <xsd:enumeration value=\"accent6\"/>\n       <xsd:enumeration value=\"hlink\"/>\n       <xsd:enumeration value=\"folHlink\"/>\n       <xsd:enumeration value=\"dk1\"/>\n       <xsd:enumeration value=\"lt1\"/>\n       <xsd:enumeration value=\"dk2\"/>\n       <xsd:enumeration value=\"lt2\"/>\n       <xsd:enumeration value=\"phClr\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_RectAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PathShadeType\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"shape\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"rect\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LineCap\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"rnd\"/>\n       <xsd:enumeration value=\"sq\"/>\n       <xsd:enumeration value=\"flat\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PresetLineDashVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"solid\"/>\n       <xsd:enumeration value=\"dot\"/>\n       <xsd:enumeration value=\"sysDot\"/>\n       <xsd:enumeration value=\"dash\"/>\n       <xsd:enumeration value=\"sysDash\"/>\n       <xsd:enumeration value=\"lgDash\"/>\n       <xsd:enumeration value=\"dashDot\"/>\n       <xsd:enumeration value=\"sysDashDot\"/>\n       <xsd:enumeration value=\"lgDashDot\"/>\n       <xsd:enumeration value=\"lgDashDotDot\"/>\n       <xsd:enumeration value=\"sysDashDotDot\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PenAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"in\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_CompoundLine\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"sng\"/>\n       <xsd:enumeration value=\"dbl\"/>\n       <xsd:enumeration value=\"thickThin\"/>\n       <xsd:enumeration value=\"thinThick\"/>\n       <xsd:enumeration value=\"tri\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_RelativeRect\">\n     <xsd:attribute name=\"l\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"t\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"r\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"b\" use=\"optional\" type=\"a:ST_Percentage\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorTransform\">\n     <xsd:choice>\n       <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\"/>\n       <xsd:element name=\"sat\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satMod\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lum\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumMod\" type=\"CT_Percentage\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SRgbColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SchemeColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorChoice\">\n     <xsd:choice>\n       <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\"/>\n       <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Color\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStop\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"pos\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStopList\">\n     <xsd:sequence>\n       <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"10\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_LinearShadeProperties\">\n     <xsd:attribute name=\"ang\" type=\"a:ST_PositiveFixedAngle\" use=\"optional\"/>\n     <xsd:attribute name=\"scaled\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PathShadeProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ShadeProperties\">\n     <xsd:choice>\n       <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\"/>\n       <xsd:element name=\"path\" type=\"CT_PathShadeProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SolidColorFillProperties\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientFillProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_FillProperties\">\n     <xsd:choice>\n       <xsd:element name=\"noFill\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\"/>\n       <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_PresetLineDashProperties\">\n     <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineDashProperties\">\n     <xsd:choice>\n       <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n     <xsd:attribute name=\"lim\" type=\"a:ST_PositivePercentage\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineJoinProperties\">\n     <xsd:choice>\n       <xsd:element name=\"round\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"bevel\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_PresetCameraType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueTop\"/>\n       <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n       <xsd:enumeration value=\"legacyObliqueLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueFront\"/>\n       <xsd:enumeration value=\"legacyObliqueRight\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueBottom\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n       <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n       <xsd:enumeration value=\"orthographicFront\"/>\n       <xsd:enumeration value=\"isometricTopUp\"/>\n       <xsd:enumeration value=\"isometricTopDown\"/>\n       <xsd:enumeration value=\"isometricBottomUp\"/>\n       <xsd:enumeration value=\"isometricBottomDown\"/>\n       <xsd:enumeration value=\"isometricLeftUp\"/>\n       <xsd:enumeration value=\"isometricLeftDown\"/>\n       <xsd:enumeration value=\"isometricRightUp\"/>\n       <xsd:enumeration value=\"isometricRightDown\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n       <xsd:enumeration value=\"obliqueTopLeft\"/>\n       <xsd:enumeration value=\"obliqueTop\"/>\n       <xsd:enumeration value=\"obliqueTopRight\"/>\n       <xsd:enumeration value=\"obliqueLeft\"/>\n       <xsd:enumeration value=\"obliqueRight\"/>\n       <xsd:enumeration value=\"obliqueBottomLeft\"/>\n       <xsd:enumeration value=\"obliqueBottom\"/>\n       <xsd:enumeration value=\"obliqueBottomRight\"/>\n       <xsd:enumeration value=\"perspectiveFront\"/>\n       <xsd:enumeration value=\"perspectiveLeft\"/>\n       <xsd:enumeration value=\"perspectiveRight\"/>\n       <xsd:enumeration value=\"perspectiveAbove\"/>\n       <xsd:enumeration value=\"perspectiveBelow\"/>\n       <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveRelaxed\"/>\n       <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Camera\">\n     <xsd:attribute name=\"prst\" use=\"required\" type=\"ST_PresetCameraType\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SphereCoords\">\n     <xsd:attribute name=\"lat\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"lon\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"rev\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_LightRigType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyFlat1\"/>\n       <xsd:enumeration value=\"legacyFlat2\"/>\n       <xsd:enumeration value=\"legacyFlat3\"/>\n       <xsd:enumeration value=\"legacyFlat4\"/>\n       <xsd:enumeration value=\"legacyNormal1\"/>\n       <xsd:enumeration value=\"legacyNormal2\"/>\n       <xsd:enumeration value=\"legacyNormal3\"/>\n       <xsd:enumeration value=\"legacyNormal4\"/>\n       <xsd:enumeration value=\"legacyHarsh1\"/>\n       <xsd:enumeration value=\"legacyHarsh2\"/>\n       <xsd:enumeration value=\"legacyHarsh3\"/>\n       <xsd:enumeration value=\"legacyHarsh4\"/>\n       <xsd:enumeration value=\"threePt\"/>\n       <xsd:enumeration value=\"balanced\"/>\n       <xsd:enumeration value=\"soft\"/>\n       <xsd:enumeration value=\"harsh\"/>\n       <xsd:enumeration value=\"flood\"/>\n       <xsd:enumeration value=\"contrasting\"/>\n       <xsd:enumeration value=\"morning\"/>\n       <xsd:enumeration value=\"sunrise\"/>\n       <xsd:enumeration value=\"sunset\"/>\n       <xsd:enumeration value=\"chilly\"/>\n       <xsd:enumeration value=\"freezing\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"twoPt\"/>\n       <xsd:enumeration value=\"glow\"/>\n       <xsd:enumeration value=\"brightRoom\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LightRigDirection\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_LightRig\">\n     <xsd:sequence>\n       <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n     <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_BevelPresetType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"relaxedInset\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"slope\"/>\n       <xsd:enumeration value=\"cross\"/>\n       <xsd:enumeration value=\"angle\"/>\n       <xsd:enumeration value=\"softRound\"/>\n       <xsd:enumeration value=\"convex\"/>\n       <xsd:enumeration value=\"coolSlant\"/>\n       <xsd:enumeration value=\"divot\"/>\n       <xsd:enumeration value=\"riblet\"/>\n       <xsd:enumeration value=\"hardEdge\"/>\n       <xsd:enumeration value=\"artDeco\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Bevel\">\n     <xsd:attribute name=\"w\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"h\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_PresetMaterialType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyMatte\"/>\n       <xsd:enumeration value=\"legacyPlastic\"/>\n       <xsd:enumeration value=\"legacyMetal\"/>\n       <xsd:enumeration value=\"legacyWireframe\"/>\n       <xsd:enumeration value=\"matte\"/>\n       <xsd:enumeration value=\"plastic\"/>\n       <xsd:enumeration value=\"metal\"/>\n       <xsd:enumeration value=\"warmMatte\"/>\n       <xsd:enumeration value=\"translucentPowder\"/>\n       <xsd:enumeration value=\"powder\"/>\n       <xsd:enumeration value=\"dkEdge\"/>\n       <xsd:enumeration value=\"softEdge\"/>\n       <xsd:enumeration value=\"clear\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"softmetal\"/>\n       <xsd:enumeration value=\"none\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Glow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Shadow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Reflection\">\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"stA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"stPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"fadeDir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_FillTextEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_TextOutlineEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"w\" use=\"optional\" type=\"a:ST_LineWidth\"/>\n     <xsd:attribute name=\"cap\" use=\"optional\" type=\"ST_LineCap\"/>\n     <xsd:attribute name=\"cmpd\" use=\"optional\" type=\"ST_CompoundLine\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_PenAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Scene3D\">\n     <xsd:sequence>\n       <xsd:element name=\"camera\" type=\"CT_Camera\"/>\n       <xsd:element name=\"lightRig\" type=\"CT_LightRig\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Props3D\">\n     <xsd:sequence>\n       <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n       <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"extrusionH\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"contourW\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrTextEffects\">\n     <xsd:sequence>\n       <xsd:element name=\"glow\" minOccurs=\"0\" type=\"CT_Glow\"/>\n       <xsd:element name=\"shadow\" minOccurs=\"0\" type=\"CT_Shadow\"/>\n       <xsd:element name=\"reflection\" minOccurs=\"0\" type=\"CT_Reflection\"/>\n       <xsd:element name=\"textOutline\" minOccurs=\"0\" type=\"CT_TextOutlineEffect\"/>\n       <xsd:element name=\"textFill\" minOccurs=\"0\" type=\"CT_FillTextEffect\"/>\n       <xsd:element name=\"scene3d\" minOccurs=\"0\" type=\"CT_Scene3D\"/>\n       <xsd:element name=\"props3d\" minOccurs=\"0\" type=\"CT_Props3D\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_Ligatures\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"standard\"/>\n       <xsd:enumeration value=\"contextual\"/>\n       <xsd:enumeration value=\"historical\"/>\n       <xsd:enumeration value=\"discretional\"/>\n       <xsd:enumeration value=\"standardContextual\"/>\n       <xsd:enumeration value=\"standardHistorical\"/>\n       <xsd:enumeration value=\"contextualHistorical\"/>\n       <xsd:enumeration value=\"standardDiscretional\"/>\n       <xsd:enumeration value=\"contextualDiscretional\"/>\n       <xsd:enumeration value=\"historicalDiscretional\"/>\n       <xsd:enumeration value=\"standardContextualHistorical\"/>\n       <xsd:enumeration value=\"standardContextualDiscretional\"/>\n       <xsd:enumeration value=\"standardHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"contextualHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"all\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Ligatures\">\n     <xsd:attribute name=\"val\" type=\"ST_Ligatures\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumForm\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"lining\"/>\n       <xsd:enumeration value=\"oldStyle\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumForm\">\n     <xsd:attribute name=\"val\" type=\"ST_NumForm\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumSpacing\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"proportional\"/>\n       <xsd:enumeration value=\"tabular\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumSpacing\">\n     <xsd:attribute name=\"val\" type=\"ST_NumSpacing\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StyleSet\">\n     <xsd:attribute name=\"id\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StylisticSets\">\n     <xsd:sequence minOccurs=\"0\">\n       <xsd:element name=\"styleSet\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_StyleSet\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrOpenType\">\n     <xsd:sequence>\n       <xsd:element name=\"ligatures\" minOccurs=\"0\" type=\"CT_Ligatures\"/>\n       <xsd:element name=\"numForm\" minOccurs=\"0\" type=\"CT_NumForm\"/>\n       <xsd:element name=\"numSpacing\" minOccurs=\"0\" type=\"CT_NumSpacing\"/>\n       <xsd:element name=\"stylisticSets\" minOccurs=\"0\" type=\"CT_StylisticSets\"/>\n       <xsd:element name=\"cntxtAlts\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:element name=\"discardImageEditingData\" type=\"CT_OnOff\"/>\n   <xsd:element name=\"defaultImageDpi\" type=\"CT_DefaultImageDpi\"/>\n   <xsd:complexType name=\"CT_DefaultImageDpi\">\n     <xsd:attribute name=\"val\" type=\"w:ST_DecimalNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"entityPicker\" type=\"w:CT_Empty\"/>\n   <xsd:complexType name=\"CT_SdtCheckboxSymbol\">\n     <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n     <xsd:attribute name=\"val\" type=\"w:ST_ShortHexNumber\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SdtCheckbox\">\n     <xsd:sequence>\n       <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n       <xsd:element name=\"checkedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n       <xsd:element name=\"uncheckedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:element name=\"checkbox\" type=\"CT_SdtCheckbox\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2012/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:element name=\"color\" type=\"w12:CT_Color\"/>\n   <xsd:simpleType name=\"ST_SdtAppearance\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"boundingBox\"/>\n       <xsd:enumeration value=\"tags\"/>\n       <xsd:enumeration value=\"hidden\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:element name=\"dataBinding\" type=\"w12:CT_DataBinding\"/>\n   <xsd:complexType name=\"CT_SdtAppearance\">\n     <xsd:attribute name=\"val\" type=\"ST_SdtAppearance\"/>\n   </xsd:complexType>\n   <xsd:element name=\"appearance\" type=\"CT_SdtAppearance\"/>\n   <xsd:complexType name=\"CT_CommentsEx\">\n     <xsd:sequence>\n       <xsd:element name=\"commentEx\" type=\"CT_CommentEx\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentEx\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"paraIdParent\" type=\"w12:ST_LongHexNumber\" use=\"optional\"/>\n     <xsd:attribute name=\"done\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsEx\" type=\"CT_CommentsEx\"/>\n   <xsd:complexType name=\"CT_People\">\n     <xsd:sequence>\n       <xsd:element name=\"person\" type=\"CT_Person\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PresenceInfo\">\n     <xsd:attribute name=\"providerId\" type=\"xsd:string\" use=\"required\"/>\n     <xsd:attribute name=\"userId\" type=\"xsd:string\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Person\">\n     <xsd:sequence>\n       <xsd:element name=\"presenceInfo\" type=\"CT_PresenceInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"people\" type=\"CT_People\"/>\n   <xsd:complexType name=\"CT_SdtRepeatedSection\">\n     <xsd:sequence>\n       <xsd:element name=\"sectionTitle\" type=\"w12:CT_String\" minOccurs=\"0\"/>\n       <xsd:element name=\"doNotAllowInsertDeleteSection\" type=\"w12:CT_OnOff\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_Guid\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Guid\">\n     <xsd:attribute name=\"val\" type=\"ST_Guid\"/>\n   </xsd:complexType>\n   <xsd:element name=\"repeatingSection\" type=\"CT_SdtRepeatedSection\"/>\n   <xsd:element name=\"repeatingSectionItem\" type=\"w12:CT_Empty\"/>\n   <xsd:element name=\"chartTrackingRefBased\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"collapsed\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"docId\" type=\"CT_Guid\"/>\n   <xsd:element name=\"footnoteColumns\" type=\"w12:CT_DecimalNumber\"/>\n   <xsd:element name=\"webExtensionLinked\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"webExtensionCreated\" type=\"w12:CT_OnOff\"/>\n   <xsd:attribute name=\"restartNumberingAfterBreak\" type=\"s:ST_OnOff\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_Extension\">\n     <xsd:sequence>\n       <xsd:any processContents=\"lax\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_ExtensionList\">\n     <xsd:sequence>\n       <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\">\n   <xsd:import id=\"w16\" namespace=\"http://schemas.microsoft.com/office/word/2018/wordml\" schemaLocation=\"wml-2018.xsd\"/>\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import id=\"s\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"commentExtensible\" type=\"CT_CommentExtensible\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"durableId\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"dateUtc\" type=\"w:ST_DateTime\" use=\"optional\"/>\n     <xsd:attribute name=\"intelligentPlaceholder\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsExtensible\" type=\"CT_CommentsExtensible\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" targetNamespace=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsIds\">\n     <xsd:sequence>\n       <xsd:element name=\"commentId\" type=\"CT_CommentId\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentId\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"durableId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsIds\" type=\"CT_CommentsIds\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" targetNamespace=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:attribute name=\"storeItemChecksum\" type=\"w12:ST_String\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_SymEx\">\n     <xsd:attribute name=\"font\" type=\"w12:ST_String\"/>\n     <xsd:attribute name=\"char\" type=\"w12:ST_LongHexNumber\"/>\n   </xsd:complexType>\n   <xsd:element name=\"symEx\" type=\"CT_SymEx\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/pack.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nTool to pack a directory into a .docx, .pptx, or .xlsx file with XML formatting undone.\n\nExample usage:\n    python pack.py <input_directory> <office_file> [--force]\n\"\"\"\n\nimport argparse\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport defusedxml.minidom\nimport zipfile\nfrom pathlib import Path\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Pack a directory into an Office file\")\n    parser.add_argument(\"input_directory\", help=\"Unpacked Office document directory\")\n    parser.add_argument(\"output_file\", help=\"Output Office file (.docx/.pptx/.xlsx)\")\n    parser.add_argument(\"--force\", action=\"store_true\", help=\"Skip validation\")\n    args = parser.parse_args()\n\n    try:\n        success = pack_document(\n            args.input_directory, args.output_file, validate=not args.force\n        )\n\n        # Show warning if validation was skipped\n        if args.force:\n            print(\"Warning: Skipped validation, file may be corrupt\", file=sys.stderr)\n        # Exit with error if validation failed\n        elif not success:\n            print(\"Contents would produce a corrupt file.\", file=sys.stderr)\n            print(\"Please validate XML before repacking.\", file=sys.stderr)\n            print(\"Use --force to skip validation and pack anyway.\", file=sys.stderr)\n            sys.exit(1)\n\n    except ValueError as e:\n        sys.exit(f\"Error: {e}\")\n\n\ndef pack_document(input_dir, output_file, validate=False):\n    \"\"\"Pack a directory into an Office file (.docx/.pptx/.xlsx).\n\n    Args:\n        input_dir: Path to unpacked Office document directory\n        output_file: Path to output Office file\n        validate: If True, validates with soffice (default: False)\n\n    Returns:\n        bool: True if successful, False if validation failed\n    \"\"\"\n    input_dir = Path(input_dir)\n    output_file = Path(output_file)\n\n    if not input_dir.is_dir():\n        raise ValueError(f\"{input_dir} is not a directory\")\n    if output_file.suffix.lower() not in {\".docx\", \".pptx\", \".xlsx\"}:\n        raise ValueError(f\"{output_file} must be a .docx, .pptx, or .xlsx file\")\n\n    # Work in temporary directory to avoid modifying original\n    with tempfile.TemporaryDirectory() as temp_dir:\n        temp_content_dir = Path(temp_dir) / \"content\"\n        shutil.copytree(input_dir, temp_content_dir)\n\n        # Process XML files to remove pretty-printing whitespace\n        for pattern in [\"*.xml\", \"*.rels\"]:\n            for xml_file in temp_content_dir.rglob(pattern):\n                condense_xml(xml_file)\n\n        # Create final Office file as zip archive\n        output_file.parent.mkdir(parents=True, exist_ok=True)\n        with zipfile.ZipFile(output_file, \"w\", zipfile.ZIP_DEFLATED) as zf:\n            for f in temp_content_dir.rglob(\"*\"):\n                if f.is_file():\n                    zf.write(f, f.relative_to(temp_content_dir))\n\n        # Validate if requested\n        if validate:\n            if not validate_document(output_file):\n                output_file.unlink()  # Delete the corrupt file\n                return False\n\n    return True\n\n\ndef validate_document(doc_path):\n    \"\"\"Validate document by converting to HTML with soffice.\"\"\"\n    # Determine the correct filter based on file extension\n    match doc_path.suffix.lower():\n        case \".docx\":\n            filter_name = \"html:HTML\"\n        case \".pptx\":\n            filter_name = \"html:impress_html_Export\"\n        case \".xlsx\":\n            filter_name = \"html:HTML (StarCalc)\"\n\n    with tempfile.TemporaryDirectory() as temp_dir:\n        try:\n            result = subprocess.run(\n                [\n                    \"soffice\",\n                    \"--headless\",\n                    \"--convert-to\",\n                    filter_name,\n                    \"--outdir\",\n                    temp_dir,\n                    str(doc_path),\n                ],\n                capture_output=True,\n                timeout=10,\n                text=True,\n            )\n            if not (Path(temp_dir) / f\"{doc_path.stem}.html\").exists():\n                error_msg = result.stderr.strip() or \"Document validation failed\"\n                print(f\"Validation error: {error_msg}\", file=sys.stderr)\n                return False\n            return True\n        except FileNotFoundError:\n            print(\"Warning: soffice not found. Skipping validation.\", file=sys.stderr)\n            return True\n        except subprocess.TimeoutExpired:\n            print(\"Validation error: Timeout during conversion\", file=sys.stderr)\n            return False\n        except Exception as e:\n            print(f\"Validation error: {e}\", file=sys.stderr)\n            return False\n\n\ndef condense_xml(xml_file):\n    \"\"\"Strip unnecessary whitespace and remove comments.\"\"\"\n    with open(xml_file, \"r\", encoding=\"utf-8\") as f:\n        dom = defusedxml.minidom.parse(f)\n\n    # Process each element to remove whitespace and comments\n    for element in dom.getElementsByTagName(\"*\"):\n        # Skip w:t elements and their processing\n        if element.tagName.endswith(\":t\"):\n            continue\n\n        # Remove whitespace-only text nodes and comment nodes\n        for child in list(element.childNodes):\n            if (\n                child.nodeType == child.TEXT_NODE\n                and child.nodeValue\n                and child.nodeValue.strip() == \"\"\n            ) or child.nodeType == child.COMMENT_NODE:\n                element.removeChild(child)\n\n    # Write back the condensed XML\n    with open(xml_file, \"wb\") as f:\n        f.write(dom.toxml(encoding=\"UTF-8\"))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/unpack.py",
    "content": "#!/usr/bin/env python3\n\"\"\"Unpack and format XML contents of Office files (.docx, .pptx, .xlsx)\"\"\"\n\nimport random\nimport sys\nimport defusedxml.minidom\nimport zipfile\nfrom pathlib import Path\n\n# Get command line arguments\nassert len(sys.argv) == 3, \"Usage: python unpack.py <office_file> <output_dir>\"\ninput_file, output_dir = sys.argv[1], sys.argv[2]\n\n# Extract and format\noutput_path = Path(output_dir)\noutput_path.mkdir(parents=True, exist_ok=True)\nzipfile.ZipFile(input_file).extractall(output_path)\n\n# Pretty print all XML files\nxml_files = list(output_path.rglob(\"*.xml\")) + list(output_path.rglob(\"*.rels\"))\nfor xml_file in xml_files:\n    content = xml_file.read_text(encoding=\"utf-8\")\n    dom = defusedxml.minidom.parseString(content)\n    xml_file.write_bytes(dom.toprettyxml(indent=\"  \", encoding=\"ascii\"))\n\n# For .docx files, suggest an RSID for tracked changes\nif input_file.endswith(\".docx\"):\n    suggested_rsid = \"\".join(random.choices(\"0123456789ABCDEF\", k=8))\n    print(f\"Suggested RSID for edit session: {suggested_rsid}\")\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validate.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nCommand line tool to validate Office document XML files against XSD schemas and tracked changes.\n\nUsage:\n    python validate.py <dir> --original <original_file>\n\"\"\"\n\nimport argparse\nimport sys\nfrom pathlib import Path\n\nfrom validation import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Validate Office document XML files\")\n    parser.add_argument(\n        \"unpacked_dir\",\n        help=\"Path to unpacked Office document directory\",\n    )\n    parser.add_argument(\n        \"--original\",\n        required=True,\n        help=\"Path to original file (.docx/.pptx/.xlsx)\",\n    )\n    parser.add_argument(\n        \"-v\",\n        \"--verbose\",\n        action=\"store_true\",\n        help=\"Enable verbose output\",\n    )\n    args = parser.parse_args()\n\n    # Validate paths\n    unpacked_dir = Path(args.unpacked_dir)\n    original_file = Path(args.original)\n    file_extension = original_file.suffix.lower()\n    assert unpacked_dir.is_dir(), f\"Error: {unpacked_dir} is not a directory\"\n    assert original_file.is_file(), f\"Error: {original_file} is not a file\"\n    assert file_extension in [\".docx\", \".pptx\", \".xlsx\"], (\n        f\"Error: {original_file} must be a .docx, .pptx, or .xlsx file\"\n    )\n\n    # Run validations\n    match file_extension:\n        case \".docx\":\n            validators = [DOCXSchemaValidator, RedliningValidator]\n        case \".pptx\":\n            validators = [PPTXSchemaValidator]\n        case _:\n            print(f\"Error: Validation not supported for file type {file_extension}\")\n            sys.exit(1)\n\n    # Run validators\n    success = True\n    for V in validators:\n        validator = V(unpacked_dir, original_file, verbose=args.verbose)\n        if not validator.validate():\n            success = False\n\n    if success:\n        print(\"All validations PASSED!\")\n\n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validation/__init__.py",
    "content": "\"\"\"\nValidation modules for Word document processing.\n\"\"\"\n\nfrom .base import BaseSchemaValidator\nfrom .docx import DOCXSchemaValidator\nfrom .pptx import PPTXSchemaValidator\nfrom .redlining import RedliningValidator\n\n__all__ = [\n    \"BaseSchemaValidator\",\n    \"DOCXSchemaValidator\",\n    \"PPTXSchemaValidator\",\n    \"RedliningValidator\",\n]\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validation/base.py",
    "content": "\"\"\"\nBase validator with common validation logic for document files.\n\"\"\"\n\nimport re\nfrom pathlib import Path\n\nimport lxml.etree\n\n\nclass BaseSchemaValidator:\n    \"\"\"Base validator with common validation logic for document files.\"\"\"\n\n    # Elements whose 'id' attributes must be unique within their file\n    # Format: element_name -> (attribute_name, scope)\n    # scope can be 'file' (unique within file) or 'global' (unique across all files)\n    UNIQUE_ID_REQUIREMENTS = {\n        # Word elements\n        \"comment\": (\"id\", \"file\"),  # Comment IDs in comments.xml\n        \"commentrangestart\": (\"id\", \"file\"),  # Must match comment IDs\n        \"commentrangeend\": (\"id\", \"file\"),  # Must match comment IDs\n        \"bookmarkstart\": (\"id\", \"file\"),  # Bookmark start IDs\n        \"bookmarkend\": (\"id\", \"file\"),  # Bookmark end IDs\n        # Note: ins and del (track changes) can share IDs when part of same revision\n        # PowerPoint elements\n        \"sldid\": (\"id\", \"file\"),  # Slide IDs in presentation.xml\n        \"sldmasterid\": (\"id\", \"global\"),  # Slide master IDs must be globally unique\n        \"sldlayoutid\": (\"id\", \"global\"),  # Slide layout IDs must be globally unique\n        \"cm\": (\"authorid\", \"file\"),  # Comment author IDs\n        # Excel elements\n        \"sheet\": (\"sheetid\", \"file\"),  # Sheet IDs in workbook.xml\n        \"definedname\": (\"id\", \"file\"),  # Named range IDs\n        # Drawing/Shape elements (all formats)\n        \"cxnsp\": (\"id\", \"file\"),  # Connection shape IDs\n        \"sp\": (\"id\", \"file\"),  # Shape IDs\n        \"pic\": (\"id\", \"file\"),  # Picture IDs\n        \"grpsp\": (\"id\", \"file\"),  # Group shape IDs\n    }\n\n    # Mapping of element names to expected relationship types\n    # Subclasses should override this with format-specific mappings\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    # Unified schema mappings for all Office document types\n    SCHEMA_MAPPINGS = {\n        # Document type specific schemas\n        \"word\": \"ISO-IEC29500-4_2016/wml.xsd\",  # Word documents\n        \"ppt\": \"ISO-IEC29500-4_2016/pml.xsd\",  # PowerPoint presentations\n        \"xl\": \"ISO-IEC29500-4_2016/sml.xsd\",  # Excel spreadsheets\n        # Common file types\n        \"[Content_Types].xml\": \"ecma/fouth-edition/opc-contentTypes.xsd\",\n        \"app.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd\",\n        \"core.xml\": \"ecma/fouth-edition/opc-coreProperties.xsd\",\n        \"custom.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd\",\n        \".rels\": \"ecma/fouth-edition/opc-relationships.xsd\",\n        # Word-specific files\n        \"people.xml\": \"microsoft/wml-2012.xsd\",\n        \"commentsIds.xml\": \"microsoft/wml-cid-2016.xsd\",\n        \"commentsExtensible.xml\": \"microsoft/wml-cex-2018.xsd\",\n        \"commentsExtended.xml\": \"microsoft/wml-2012.xsd\",\n        # Chart files (common across document types)\n        \"chart\": \"ISO-IEC29500-4_2016/dml-chart.xsd\",\n        # Theme files (common across document types)\n        \"theme\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n        # Drawing and media files\n        \"drawing\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n    }\n\n    # Unified namespace constants\n    MC_NAMESPACE = \"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\"\n\n    # Common OOXML namespaces used across validators\n    PACKAGE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/relationships\"\n    )\n    OFFICE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    )\n    CONTENT_TYPES_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/content-types\"\n    )\n\n    # Folders where we should clean ignorable namespaces\n    MAIN_CONTENT_FOLDERS = {\"word\", \"ppt\", \"xl\"}\n\n    # All allowed OOXML namespaces (superset of all document types)\n    OOXML_NAMESPACES = {\n        \"http://schemas.openxmlformats.org/officeDocument/2006/math\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n        \"http://schemas.openxmlformats.org/schemaLibrary/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chart\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/diagram\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n        \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\",\n        \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\",\n        \"http://www.w3.org/XML/1998/namespace\",\n    }\n\n    def __init__(self, unpacked_dir, original_file, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir).resolve()\n        self.original_file = Path(original_file)\n        self.verbose = verbose\n\n        # Set schemas directory\n        self.schemas_dir = Path(__file__).parent.parent.parent / \"schemas\"\n\n        # Get all XML and .rels files\n        patterns = [\"*.xml\", \"*.rels\"]\n        self.xml_files = [\n            f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)\n        ]\n\n        if not self.xml_files:\n            print(f\"Warning: No XML files found in {self.unpacked_dir}\")\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        raise NotImplementedError(\"Subclasses must implement the validate method\")\n\n    def validate_xml(self):\n        \"\"\"Validate that all XML files are well-formed.\"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                # Try to parse the XML file\n                lxml.etree.parse(str(xml_file))\n            except lxml.etree.XMLSyntaxError as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Line {e.lineno}: {e.msg}\"\n                )\n            except Exception as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Unexpected error: {str(e)}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} XML violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All XML files are well-formed\")\n            return True\n\n    def validate_namespaces(self):\n        \"\"\"Validate that namespace prefixes in Ignorable attributes are declared.\"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                declared = set(root.nsmap.keys()) - {None}  # Exclude default namespace\n\n                for attr_val in [\n                    v for k, v in root.attrib.items() if k.endswith(\"Ignorable\")\n                ]:\n                    undeclared = set(attr_val.split()) - declared\n                    errors.extend(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Namespace '{ns}' in Ignorable but not declared\"\n                        for ns in undeclared\n                    )\n            except lxml.etree.XMLSyntaxError:\n                continue\n\n        if errors:\n            print(f\"FAILED - {len(errors)} namespace issues:\")\n            for error in errors:\n                print(error)\n            return False\n        if self.verbose:\n            print(\"PASSED - All namespace prefixes properly declared\")\n        return True\n\n    def validate_unique_ids(self):\n        \"\"\"Validate that specific IDs are unique according to OOXML requirements.\"\"\"\n        errors = []\n        global_ids = {}  # Track globally unique IDs across all files\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                file_ids = {}  # Track IDs that must be unique within this file\n\n                # Remove all mc:AlternateContent elements from the tree\n                mc_elements = root.xpath(\n                    \".//mc:AlternateContent\", namespaces={\"mc\": self.MC_NAMESPACE}\n                )\n                for elem in mc_elements:\n                    elem.getparent().remove(elem)\n\n                # Now check IDs in the cleaned tree\n                for elem in root.iter():\n                    # Get the element name without namespace\n                    tag = (\n                        elem.tag.split(\"}\")[-1].lower()\n                        if \"}\" in elem.tag\n                        else elem.tag.lower()\n                    )\n\n                    # Check if this element type has ID uniqueness requirements\n                    if tag in self.UNIQUE_ID_REQUIREMENTS:\n                        attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]\n\n                        # Look for the specified attribute\n                        id_value = None\n                        for attr, value in elem.attrib.items():\n                            attr_local = (\n                                attr.split(\"}\")[-1].lower()\n                                if \"}\" in attr\n                                else attr.lower()\n                            )\n                            if attr_local == attr_name:\n                                id_value = value\n                                break\n\n                        if id_value is not None:\n                            if scope == \"global\":\n                                # Check global uniqueness\n                                if id_value in global_ids:\n                                    prev_file, prev_line, prev_tag = global_ids[\n                                        id_value\n                                    ]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> \"\n                                        f\"already used in {prev_file} at line {prev_line} in <{prev_tag}>\"\n                                    )\n                                else:\n                                    global_ids[id_value] = (\n                                        xml_file.relative_to(self.unpacked_dir),\n                                        elem.sourceline,\n                                        tag,\n                                    )\n                            elif scope == \"file\":\n                                # Check file-level uniqueness\n                                key = (tag, attr_name)\n                                if key not in file_ids:\n                                    file_ids[key] = {}\n\n                                if id_value in file_ids[key]:\n                                    prev_line = file_ids[key][id_value]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> \"\n                                        f\"(first occurrence at line {prev_line})\"\n                                    )\n                                else:\n                                    file_ids[key][id_value] = elem.sourceline\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} ID uniqueness violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All required IDs are unique\")\n            return True\n\n    def validate_file_references(self):\n        \"\"\"\n        Validate that all .rels files properly reference files and that all files are referenced.\n        \"\"\"\n        errors = []\n\n        # Find all .rels files\n        rels_files = list(self.unpacked_dir.rglob(\"*.rels\"))\n\n        if not rels_files:\n            if self.verbose:\n                print(\"PASSED - No .rels files found\")\n            return True\n\n        # Get all files in the unpacked directory (excluding reference files)\n        all_files = []\n        for file_path in self.unpacked_dir.rglob(\"*\"):\n            if (\n                file_path.is_file()\n                and file_path.name != \"[Content_Types].xml\"\n                and not file_path.name.endswith(\".rels\")\n            ):  # This file is not referenced by .rels\n                all_files.append(file_path.resolve())\n\n        # Track all files that are referenced by any .rels file\n        all_referenced_files = set()\n\n        if self.verbose:\n            print(\n                f\"Found {len(rels_files)} .rels files and {len(all_files)} target files\"\n            )\n\n        # Check each .rels file\n        for rels_file in rels_files:\n            try:\n                # Parse relationships file\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Get the directory where this .rels file is located\n                rels_dir = rels_file.parent\n\n                # Find all relationships and their targets\n                referenced_files = set()\n                broken_refs = []\n\n                for rel in rels_root.findall(\n                    \".//ns:Relationship\",\n                    namespaces={\"ns\": self.PACKAGE_RELATIONSHIPS_NAMESPACE},\n                ):\n                    target = rel.get(\"Target\")\n                    if target and not target.startswith(\n                        (\"http\", \"mailto:\")\n                    ):  # Skip external URLs\n                        # Resolve the target path relative to the .rels file location\n                        if rels_file.name == \".rels\":\n                            # Root .rels file - targets are relative to unpacked_dir\n                            target_path = self.unpacked_dir / target\n                        else:\n                            # Other .rels files - targets are relative to their parent's parent\n                            # e.g., word/_rels/document.xml.rels -> targets relative to word/\n                            base_dir = rels_dir.parent\n                            target_path = base_dir / target\n\n                        # Normalize the path and check if it exists\n                        try:\n                            target_path = target_path.resolve()\n                            if target_path.exists() and target_path.is_file():\n                                referenced_files.add(target_path)\n                                all_referenced_files.add(target_path)\n                            else:\n                                broken_refs.append((target, rel.sourceline))\n                        except (OSError, ValueError):\n                            broken_refs.append((target, rel.sourceline))\n\n                # Report broken references\n                if broken_refs:\n                    rel_path = rels_file.relative_to(self.unpacked_dir)\n                    for broken_ref, line_num in broken_refs:\n                        errors.append(\n                            f\"  {rel_path}: Line {line_num}: Broken reference to {broken_ref}\"\n                        )\n\n            except Exception as e:\n                rel_path = rels_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error parsing {rel_path}: {e}\")\n\n        # Check for unreferenced files (files that exist but are not referenced anywhere)\n        unreferenced_files = set(all_files) - all_referenced_files\n\n        if unreferenced_files:\n            for unref_file in sorted(unreferenced_files):\n                unref_rel_path = unref_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Unreferenced file: {unref_rel_path}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"CRITICAL: These errors will cause the document to appear corrupt. \"\n                + \"Broken references MUST be fixed, \"\n                + \"and unreferenced files MUST be referenced or removed.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All references are valid and all files are properly referenced\"\n                )\n            return True\n\n    def validate_all_relationship_ids(self):\n        \"\"\"\n        Validate that all r:id attributes in XML files reference existing IDs\n        in their corresponding .rels files, and optionally validate relationship types.\n        \"\"\"\n        import lxml.etree\n\n        errors = []\n\n        # Process each XML file that might contain r:id references\n        for xml_file in self.xml_files:\n            # Skip .rels files themselves\n            if xml_file.suffix == \".rels\":\n                continue\n\n            # Determine the corresponding .rels file\n            # For dir/file.xml, it's dir/_rels/file.xml.rels\n            rels_dir = xml_file.parent / \"_rels\"\n            rels_file = rels_dir / f\"{xml_file.name}.rels\"\n\n            # Skip if there's no corresponding .rels file (that's okay)\n            if not rels_file.exists():\n                continue\n\n            try:\n                # Parse the .rels file to get valid relationship IDs and their types\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n                rid_to_type = {}\n\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rid = rel.get(\"Id\")\n                    rel_type = rel.get(\"Type\", \"\")\n                    if rid:\n                        # Check for duplicate rIds\n                        if rid in rid_to_type:\n                            rels_rel_path = rels_file.relative_to(self.unpacked_dir)\n                            errors.append(\n                                f\"  {rels_rel_path}: Line {rel.sourceline}: \"\n                                f\"Duplicate relationship ID '{rid}' (IDs must be unique)\"\n                            )\n                        # Extract just the type name from the full URL\n                        type_name = (\n                            rel_type.split(\"/\")[-1] if \"/\" in rel_type else rel_type\n                        )\n                        rid_to_type[rid] = type_name\n\n                # Parse the XML file to find all r:id references\n                xml_root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all elements with r:id attributes\n                for elem in xml_root.iter():\n                    # Check for r:id attribute (relationship ID)\n                    rid_attr = elem.get(f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\")\n                    if rid_attr:\n                        xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                        elem_name = (\n                            elem.tag.split(\"}\")[-1] if \"}\" in elem.tag else elem.tag\n                        )\n\n                        # Check if the ID exists\n                        if rid_attr not in rid_to_type:\n                            errors.append(\n                                f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                f\"<{elem_name}> references non-existent relationship '{rid_attr}' \"\n                                f\"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})\"\n                            )\n                        # Check if we have type expectations for this element\n                        elif self.ELEMENT_RELATIONSHIP_TYPES:\n                            expected_type = self._get_expected_relationship_type(\n                                elem_name\n                            )\n                            if expected_type:\n                                actual_type = rid_to_type[rid_attr]\n                                # Check if the actual type matches or contains the expected type\n                                if expected_type not in actual_type.lower():\n                                    errors.append(\n                                        f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                        f\"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' \"\n                                        f\"but should point to a '{expected_type}' relationship\"\n                                    )\n\n            except Exception as e:\n                xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error processing {xml_rel_path}: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship ID reference errors:\")\n            for error in errors:\n                print(error)\n            print(\"\\nThese ID mismatches will cause the document to appear corrupt!\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All relationship ID references are valid\")\n            return True\n\n    def _get_expected_relationship_type(self, element_name):\n        \"\"\"\n        Get the expected relationship type for an element.\n        First checks the explicit mapping, then tries pattern detection.\n        \"\"\"\n        # Normalize element name to lowercase\n        elem_lower = element_name.lower()\n\n        # Check explicit mapping first\n        if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:\n            return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]\n\n        # Try pattern detection for common patterns\n        # Pattern 1: Elements ending in \"Id\" often expect a relationship of the prefix type\n        if elem_lower.endswith(\"id\") and len(elem_lower) > 2:\n            # e.g., \"sldId\" -> \"sld\", \"sldMasterId\" -> \"sldMaster\"\n            prefix = elem_lower[:-2]  # Remove \"id\"\n            # Check if this might be a compound like \"sldMasterId\"\n            if prefix.endswith(\"master\"):\n                return prefix.lower()\n            elif prefix.endswith(\"layout\"):\n                return prefix.lower()\n            else:\n                # Simple case like \"sldId\" -> \"slide\"\n                # Common transformations\n                if prefix == \"sld\":\n                    return \"slide\"\n                return prefix.lower()\n\n        # Pattern 2: Elements ending in \"Reference\" expect a relationship of the prefix type\n        if elem_lower.endswith(\"reference\") and len(elem_lower) > 9:\n            prefix = elem_lower[:-9]  # Remove \"reference\"\n            return prefix.lower()\n\n        return None\n\n    def validate_content_types(self):\n        \"\"\"Validate that all content files are properly declared in [Content_Types].xml.\"\"\"\n        errors = []\n\n        # Find [Content_Types].xml file\n        content_types_file = self.unpacked_dir / \"[Content_Types].xml\"\n        if not content_types_file.exists():\n            print(\"FAILED - [Content_Types].xml file not found\")\n            return False\n\n        try:\n            # Parse and get all declared parts and extensions\n            root = lxml.etree.parse(str(content_types_file)).getroot()\n            declared_parts = set()\n            declared_extensions = set()\n\n            # Get Override declarations (specific files)\n            for override in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override\"\n            ):\n                part_name = override.get(\"PartName\")\n                if part_name is not None:\n                    declared_parts.add(part_name.lstrip(\"/\"))\n\n            # Get Default declarations (by extension)\n            for default in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default\"\n            ):\n                extension = default.get(\"Extension\")\n                if extension is not None:\n                    declared_extensions.add(extension.lower())\n\n            # Root elements that require content type declaration\n            declarable_roots = {\n                \"sld\",\n                \"sldLayout\",\n                \"sldMaster\",\n                \"presentation\",  # PowerPoint\n                \"document\",  # Word\n                \"workbook\",\n                \"worksheet\",  # Excel\n                \"theme\",  # Common\n            }\n\n            # Common media file extensions that should be declared\n            media_extensions = {\n                \"png\": \"image/png\",\n                \"jpg\": \"image/jpeg\",\n                \"jpeg\": \"image/jpeg\",\n                \"gif\": \"image/gif\",\n                \"bmp\": \"image/bmp\",\n                \"tiff\": \"image/tiff\",\n                \"wmf\": \"image/x-wmf\",\n                \"emf\": \"image/x-emf\",\n            }\n\n            # Get all files in the unpacked directory\n            all_files = list(self.unpacked_dir.rglob(\"*\"))\n            all_files = [f for f in all_files if f.is_file()]\n\n            # Check all XML files for Override declarations\n            for xml_file in self.xml_files:\n                path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(\n                    \"\\\\\", \"/\"\n                )\n\n                # Skip non-content files\n                if any(\n                    skip in path_str\n                    for skip in [\".rels\", \"[Content_Types]\", \"docProps/\", \"_rels/\"]\n                ):\n                    continue\n\n                try:\n                    root_tag = lxml.etree.parse(str(xml_file)).getroot().tag\n                    root_name = root_tag.split(\"}\")[-1] if \"}\" in root_tag else root_tag\n\n                    if root_name in declarable_roots and path_str not in declared_parts:\n                        errors.append(\n                            f\"  {path_str}: File with <{root_name}> root not declared in [Content_Types].xml\"\n                        )\n\n                except Exception:\n                    continue  # Skip unparseable files\n\n            # Check all non-XML files for Default extension declarations\n            for file_path in all_files:\n                # Skip XML files and metadata files (already checked above)\n                if file_path.suffix.lower() in {\".xml\", \".rels\"}:\n                    continue\n                if file_path.name == \"[Content_Types].xml\":\n                    continue\n                if \"_rels\" in file_path.parts or \"docProps\" in file_path.parts:\n                    continue\n\n                extension = file_path.suffix.lstrip(\".\").lower()\n                if extension and extension not in declared_extensions:\n                    # Check if it's a known media extension that should be declared\n                    if extension in media_extensions:\n                        relative_path = file_path.relative_to(self.unpacked_dir)\n                        errors.append(\n                            f'  {relative_path}: File with extension \\'{extension}\\' not declared in [Content_Types].xml - should add: <Default Extension=\"{extension}\" ContentType=\"{media_extensions[extension]}\"/>'\n                        )\n\n        except Exception as e:\n            errors.append(f\"  Error parsing [Content_Types].xml: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} content type declaration errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All content files are properly declared in [Content_Types].xml\"\n                )\n            return True\n\n    def validate_file_against_xsd(self, xml_file, verbose=False):\n        \"\"\"Validate a single XML file against XSD schema, comparing with original.\n\n        Args:\n            xml_file: Path to XML file to validate\n            verbose: Enable verbose output\n\n        Returns:\n            tuple: (is_valid, new_errors_set) where is_valid is True/False/None (skipped)\n        \"\"\"\n        # Resolve both paths to handle symlinks\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n\n        # Validate current file\n        is_valid, current_errors = self._validate_single_file_xsd(\n            xml_file, unpacked_dir\n        )\n\n        if is_valid is None:\n            return None, set()  # Skipped\n        elif is_valid:\n            return True, set()  # Valid, no errors\n\n        # Get errors from original file for this specific file\n        original_errors = self._get_original_file_errors(xml_file)\n\n        # Compare with original (both are guaranteed to be sets here)\n        assert current_errors is not None\n        new_errors = current_errors - original_errors\n\n        if new_errors:\n            if verbose:\n                relative_path = xml_file.relative_to(unpacked_dir)\n                print(f\"FAILED - {relative_path}: {len(new_errors)} new error(s)\")\n                for error in list(new_errors)[:3]:\n                    truncated = error[:250] + \"...\" if len(error) > 250 else error\n                    print(f\"  - {truncated}\")\n            return False, new_errors\n        else:\n            # All errors existed in original\n            if verbose:\n                print(\n                    f\"PASSED - No new errors (original had {len(current_errors)} errors)\"\n                )\n            return True, set()\n\n    def validate_against_xsd(self):\n        \"\"\"Validate XML files against XSD schemas, showing only new errors compared to original.\"\"\"\n        new_errors = []\n        original_error_count = 0\n        valid_count = 0\n        skipped_count = 0\n\n        for xml_file in self.xml_files:\n            relative_path = str(xml_file.relative_to(self.unpacked_dir))\n            is_valid, new_file_errors = self.validate_file_against_xsd(\n                xml_file, verbose=False\n            )\n\n            if is_valid is None:\n                skipped_count += 1\n                continue\n            elif is_valid and not new_file_errors:\n                valid_count += 1\n                continue\n            elif is_valid:\n                # Had errors but all existed in original\n                original_error_count += 1\n                valid_count += 1\n                continue\n\n            # Has new errors\n            new_errors.append(f\"  {relative_path}: {len(new_file_errors)} new error(s)\")\n            for error in list(new_file_errors)[:3]:  # Show first 3 errors\n                new_errors.append(\n                    f\"    - {error[:250]}...\" if len(error) > 250 else f\"    - {error}\"\n                )\n\n        # Print summary\n        if self.verbose:\n            print(f\"Validated {len(self.xml_files)} files:\")\n            print(f\"  - Valid: {valid_count}\")\n            print(f\"  - Skipped (no schema): {skipped_count}\")\n            if original_error_count:\n                print(f\"  - With original errors (ignored): {original_error_count}\")\n            print(\n                f\"  - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith('    ')]) or 0}\"\n            )\n\n        if new_errors:\n            print(\"\\nFAILED - Found NEW validation errors:\")\n            for error in new_errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"\\nPASSED - No new XSD validation errors introduced\")\n            return True\n\n    def _get_schema_path(self, xml_file):\n        \"\"\"Determine the appropriate schema path for an XML file.\"\"\"\n        # Check exact filename match\n        if xml_file.name in self.SCHEMA_MAPPINGS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]\n\n        # Check .rels files\n        if xml_file.suffix == \".rels\":\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\".rels\"]\n\n        # Check chart files\n        if \"charts/\" in str(xml_file) and xml_file.name.startswith(\"chart\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"chart\"]\n\n        # Check theme files\n        if \"theme/\" in str(xml_file) and xml_file.name.startswith(\"theme\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"theme\"]\n\n        # Check if file is in a main content folder and use appropriate schema\n        if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]\n\n        return None\n\n    def _clean_ignorable_namespaces(self, xml_doc):\n        \"\"\"Remove attributes and elements not in allowed namespaces.\"\"\"\n        # Create a clean copy\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        # Remove attributes not in allowed namespaces\n        for elem in xml_copy.iter():\n            attrs_to_remove = []\n\n            for attr in elem.attrib:\n                # Check if attribute is from a namespace other than allowed ones\n                if \"{\" in attr:\n                    ns = attr.split(\"}\")[0][1:]\n                    if ns not in self.OOXML_NAMESPACES:\n                        attrs_to_remove.append(attr)\n\n            # Remove collected attributes\n            for attr in attrs_to_remove:\n                del elem.attrib[attr]\n\n        # Remove elements not in allowed namespaces\n        self._remove_ignorable_elements(xml_copy)\n\n        return lxml.etree.ElementTree(xml_copy)\n\n    def _remove_ignorable_elements(self, root):\n        \"\"\"Recursively remove all elements not in allowed namespaces.\"\"\"\n        elements_to_remove = []\n\n        # Find elements to remove\n        for elem in list(root):\n            # Skip non-element nodes (comments, processing instructions, etc.)\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n\n            tag_str = str(elem.tag)\n            if tag_str.startswith(\"{\"):\n                ns = tag_str.split(\"}\")[0][1:]\n                if ns not in self.OOXML_NAMESPACES:\n                    elements_to_remove.append(elem)\n                    continue\n\n            # Recursively clean child elements\n            self._remove_ignorable_elements(elem)\n\n        # Remove collected elements\n        for elem in elements_to_remove:\n            root.remove(elem)\n\n    def _preprocess_for_mc_ignorable(self, xml_doc):\n        \"\"\"Preprocess XML to handle mc:Ignorable attribute properly.\"\"\"\n        # Remove mc:Ignorable attributes before validation\n        root = xml_doc.getroot()\n\n        # Remove mc:Ignorable attribute from root\n        if f\"{{{self.MC_NAMESPACE}}}Ignorable\" in root.attrib:\n            del root.attrib[f\"{{{self.MC_NAMESPACE}}}Ignorable\"]\n\n        return xml_doc\n\n    def _validate_single_file_xsd(self, xml_file, base_path):\n        \"\"\"Validate a single XML file against XSD schema. Returns (is_valid, errors_set).\"\"\"\n        schema_path = self._get_schema_path(xml_file)\n        if not schema_path:\n            return None, None  # Skip file\n\n        try:\n            # Load schema\n            with open(schema_path, \"rb\") as xsd_file:\n                parser = lxml.etree.XMLParser()\n                xsd_doc = lxml.etree.parse(\n                    xsd_file, parser=parser, base_url=str(schema_path)\n                )\n                schema = lxml.etree.XMLSchema(xsd_doc)\n\n            # Load and preprocess XML\n            with open(xml_file, \"r\") as f:\n                xml_doc = lxml.etree.parse(f)\n\n            xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)\n            xml_doc = self._preprocess_for_mc_ignorable(xml_doc)\n\n            # Clean ignorable namespaces if needed\n            relative_path = xml_file.relative_to(base_path)\n            if (\n                relative_path.parts\n                and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS\n            ):\n                xml_doc = self._clean_ignorable_namespaces(xml_doc)\n\n            # Validate\n            if schema.validate(xml_doc):\n                return True, set()\n            else:\n                errors = set()\n                for error in schema.error_log:\n                    # Store normalized error message (without line numbers for comparison)\n                    errors.add(error.message)\n                return False, errors\n\n        except Exception as e:\n            return False, {str(e)}\n\n    def _get_original_file_errors(self, xml_file):\n        \"\"\"Get XSD validation errors from a single file in the original document.\n\n        Args:\n            xml_file: Path to the XML file in unpacked_dir to check\n\n        Returns:\n            set: Set of error messages from the original file\n        \"\"\"\n        import tempfile\n        import zipfile\n\n        # Resolve both paths to handle symlinks (e.g., /var vs /private/var on macOS)\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n        relative_path = xml_file.relative_to(unpacked_dir)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            # Extract original file\n            with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                zip_ref.extractall(temp_path)\n\n            # Find corresponding file in original\n            original_xml_file = temp_path / relative_path\n\n            if not original_xml_file.exists():\n                # File didn't exist in original, so no original errors\n                return set()\n\n            # Validate the specific file in original\n            is_valid, errors = self._validate_single_file_xsd(\n                original_xml_file, temp_path\n            )\n            return errors if errors else set()\n\n    def _remove_template_tags_from_text_nodes(self, xml_doc):\n        \"\"\"Remove template tags from XML text nodes and collect warnings.\n\n        Template tags follow the pattern {{ ... }} and are used as placeholders\n        for content replacement. They should be removed from text content before\n        XSD validation while preserving XML structure.\n\n        Returns:\n            tuple: (cleaned_xml_doc, warnings_list)\n        \"\"\"\n        warnings = []\n        template_pattern = re.compile(r\"\\{\\{[^}]*\\}\\}\")\n\n        # Create a copy of the document to avoid modifying the original\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        def process_text_content(text, content_type):\n            if not text:\n                return text\n            matches = list(template_pattern.finditer(text))\n            if matches:\n                for match in matches:\n                    warnings.append(\n                        f\"Found template tag in {content_type}: {match.group()}\"\n                    )\n                return template_pattern.sub(\"\", text)\n            return text\n\n        # Process all text nodes in the document\n        for elem in xml_copy.iter():\n            # Skip processing if this is a w:t element\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n            tag_str = str(elem.tag)\n            if tag_str.endswith(\"}t\") or tag_str == \"t\":\n                continue\n\n            elem.text = process_text_content(elem.text, \"text content\")\n            elem.tail = process_text_content(elem.tail, \"tail content\")\n\n        return lxml.etree.ElementTree(xml_copy), warnings\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validation/docx.py",
    "content": "\"\"\"\nValidator for Word document XML files against XSD schemas.\n\"\"\"\n\nimport re\nimport tempfile\nimport zipfile\n\nimport lxml.etree\n\nfrom .base import BaseSchemaValidator\n\n\nclass DOCXSchemaValidator(BaseSchemaValidator):\n    \"\"\"Validator for Word document XML files against XSD schemas.\"\"\"\n\n    # Word-specific namespace\n    WORD_2006_NAMESPACE = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\n    # Word-specific element to relationship type mappings\n    # Start with empty mapping - add specific cases as we discover them\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        # Test 0: XML well-formedness\n        if not self.validate_xml():\n            return False\n\n        # Test 1: Namespace declarations\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        # Test 2: Unique IDs\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        # Test 3: Relationship and file reference validation\n        if not self.validate_file_references():\n            all_valid = False\n\n        # Test 4: Content type declarations\n        if not self.validate_content_types():\n            all_valid = False\n\n        # Test 5: XSD schema validation\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        # Test 6: Whitespace preservation\n        if not self.validate_whitespace_preservation():\n            all_valid = False\n\n        # Test 7: Deletion validation\n        if not self.validate_deletions():\n            all_valid = False\n\n        # Test 8: Insertion validation\n        if not self.validate_insertions():\n            all_valid = False\n\n        # Test 9: Relationship ID reference validation\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        # Count and compare paragraphs\n        self.compare_paragraph_counts()\n\n        return all_valid\n\n    def validate_whitespace_preservation(self):\n        \"\"\"\n        Validate that w:t elements with whitespace have xml:space='preserve'.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all w:t elements\n                for elem in root.iter(f\"{{{self.WORD_2006_NAMESPACE}}}t\"):\n                    if elem.text:\n                        text = elem.text\n                        # Check if text starts or ends with whitespace\n                        if re.match(r\"^\\s.*\", text) or re.match(r\".*\\s$\", text):\n                            # Check if xml:space=\"preserve\" attribute exists\n                            xml_space_attr = f\"{{{self.XML_NAMESPACE}}}space\"\n                            if (\n                                xml_space_attr not in elem.attrib\n                                or elem.attrib[xml_space_attr] != \"preserve\"\n                            ):\n                                # Show a preview of the text\n                                text_preview = (\n                                    repr(text)[:50] + \"...\"\n                                    if len(repr(text)) > 50\n                                    else repr(text)\n                                )\n                                errors.append(\n                                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                    f\"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}\"\n                                )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} whitespace preservation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All whitespace is properly preserved\")\n            return True\n\n    def validate_deletions(self):\n        \"\"\"\n        Validate that w:t elements are not within w:del elements.\n        For some reason, XSD validation does not catch this, so we do it manually.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all w:t elements that are descendants of w:del elements\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n                xpath_expression = \".//w:del//w:t\"\n                problematic_t_elements = root.xpath(\n                    xpath_expression, namespaces=namespaces\n                )\n                for t_elem in problematic_t_elements:\n                    if t_elem.text:\n                        # Show a preview of the text\n                        text_preview = (\n                            repr(t_elem.text)[:50] + \"...\"\n                            if len(repr(t_elem.text)) > 50\n                            else repr(t_elem.text)\n                        )\n                        errors.append(\n                            f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} deletion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:t elements found within w:del elements\")\n            return True\n\n    def count_paragraphs_in_unpacked(self):\n        \"\"\"Count the number of paragraphs in the unpacked document.\"\"\"\n        count = 0\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                # Count all w:p elements\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n            except Exception as e:\n                print(f\"Error counting paragraphs in unpacked document: {e}\")\n\n        return count\n\n    def count_paragraphs_in_original(self):\n        \"\"\"Count the number of paragraphs in the original docx file.\"\"\"\n        count = 0\n\n        try:\n            # Create temporary directory to unpack original\n            with tempfile.TemporaryDirectory() as temp_dir:\n                # Unpack original docx\n                with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_dir)\n\n                # Parse document.xml\n                doc_xml_path = temp_dir + \"/word/document.xml\"\n                root = lxml.etree.parse(doc_xml_path).getroot()\n\n                # Count all w:p elements\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n\n        except Exception as e:\n            print(f\"Error counting paragraphs in original document: {e}\")\n\n        return count\n\n    def validate_insertions(self):\n        \"\"\"\n        Validate that w:delText elements are not within w:ins elements.\n        w:delText is only allowed in w:ins if nested within a w:del.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                # Find w:delText in w:ins that are NOT within w:del\n                invalid_elements = root.xpath(\n                    \".//w:ins//w:delText[not(ancestor::w:del)]\",\n                    namespaces=namespaces\n                )\n\n                for elem in invalid_elements:\n                    text_preview = (\n                        repr(elem.text or \"\")[:50] + \"...\"\n                        if len(repr(elem.text or \"\")) > 50\n                        else repr(elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} insertion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:delText elements within w:ins elements\")\n            return True\n\n    def compare_paragraph_counts(self):\n        \"\"\"Compare paragraph counts between original and new document.\"\"\"\n        original_count = self.count_paragraphs_in_original()\n        new_count = self.count_paragraphs_in_unpacked()\n\n        diff = new_count - original_count\n        diff_str = f\"+{diff}\" if diff > 0 else str(diff)\n        print(f\"\\nParagraphs: {original_count} → {new_count} ({diff_str})\")\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validation/pptx.py",
    "content": "\"\"\"\nValidator for PowerPoint presentation XML files against XSD schemas.\n\"\"\"\n\nimport re\n\nfrom .base import BaseSchemaValidator\n\n\nclass PPTXSchemaValidator(BaseSchemaValidator):\n    \"\"\"Validator for PowerPoint presentation XML files against XSD schemas.\"\"\"\n\n    # PowerPoint presentation namespace\n    PRESENTATIONML_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\"\n    )\n\n    # PowerPoint-specific element to relationship type mappings\n    ELEMENT_RELATIONSHIP_TYPES = {\n        \"sldid\": \"slide\",\n        \"sldmasterid\": \"slidemaster\",\n        \"notesmasterid\": \"notesmaster\",\n        \"sldlayoutid\": \"slidelayout\",\n        \"themeid\": \"theme\",\n        \"tablestyleid\": \"tablestyles\",\n    }\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        # Test 0: XML well-formedness\n        if not self.validate_xml():\n            return False\n\n        # Test 1: Namespace declarations\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        # Test 2: Unique IDs\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        # Test 3: UUID ID validation\n        if not self.validate_uuid_ids():\n            all_valid = False\n\n        # Test 4: Relationship and file reference validation\n        if not self.validate_file_references():\n            all_valid = False\n\n        # Test 5: Slide layout ID validation\n        if not self.validate_slide_layout_ids():\n            all_valid = False\n\n        # Test 6: Content type declarations\n        if not self.validate_content_types():\n            all_valid = False\n\n        # Test 7: XSD schema validation\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        # Test 8: Notes slide reference validation\n        if not self.validate_notes_slide_references():\n            all_valid = False\n\n        # Test 9: Relationship ID reference validation\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        # Test 10: Duplicate slide layout references validation\n        if not self.validate_no_duplicate_slide_layouts():\n            all_valid = False\n\n        return all_valid\n\n    def validate_uuid_ids(self):\n        \"\"\"Validate that ID attributes that look like UUIDs contain only hex values.\"\"\"\n        import lxml.etree\n\n        errors = []\n        # UUID pattern: 8-4-4-4-12 hex digits with optional braces/hyphens\n        uuid_pattern = re.compile(\n            r\"^[\\{\\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\\}\\)]?$\"\n        )\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Check all elements for ID attributes\n                for elem in root.iter():\n                    for attr, value in elem.attrib.items():\n                        # Check if this is an ID attribute\n                        attr_name = attr.split(\"}\")[-1].lower()\n                        if attr_name == \"id\" or attr_name.endswith(\"id\"):\n                            # Check if value looks like a UUID (has the right length and pattern structure)\n                            if self._looks_like_uuid(value):\n                                # Validate that it contains only hex characters in the right positions\n                                if not uuid_pattern.match(value):\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters\"\n                                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} UUID ID validation errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All UUID-like IDs contain valid hex values\")\n            return True\n\n    def _looks_like_uuid(self, value):\n        \"\"\"Check if a value has the general structure of a UUID.\"\"\"\n        # Remove common UUID delimiters\n        clean_value = value.strip(\"{}()\").replace(\"-\", \"\")\n        # Check if it's 32 hex-like characters (could include invalid hex chars)\n        return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)\n\n    def validate_slide_layout_ids(self):\n        \"\"\"Validate that sldLayoutId elements in slide masters reference valid slide layouts.\"\"\"\n        import lxml.etree\n\n        errors = []\n\n        # Find all slide master files\n        slide_masters = list(self.unpacked_dir.glob(\"ppt/slideMasters/*.xml\"))\n\n        if not slide_masters:\n            if self.verbose:\n                print(\"PASSED - No slide masters found\")\n            return True\n\n        for slide_master in slide_masters:\n            try:\n                # Parse the slide master file\n                root = lxml.etree.parse(str(slide_master)).getroot()\n\n                # Find the corresponding _rels file for this slide master\n                rels_file = slide_master.parent / \"_rels\" / f\"{slide_master.name}.rels\"\n\n                if not rels_file.exists():\n                    errors.append(\n                        f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                        f\"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}\"\n                    )\n                    continue\n\n                # Parse the relationships file\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Build a set of valid relationship IDs that point to slide layouts\n                valid_layout_rids = set()\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"slideLayout\" in rel_type:\n                        valid_layout_rids.add(rel.get(\"Id\"))\n\n                # Find all sldLayoutId elements in the slide master\n                for sld_layout_id in root.findall(\n                    f\".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId\"\n                ):\n                    r_id = sld_layout_id.get(\n                        f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\"\n                    )\n                    layout_id = sld_layout_id.get(\"id\")\n\n                    if r_id and r_id not in valid_layout_rids:\n                        errors.append(\n                            f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' \"\n                            f\"references r:id='{r_id}' which is not found in slide layout relationships\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {slide_master.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} slide layout ID validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"Remove invalid references or add missing slide layouts to the relationships file.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slide layout IDs reference valid slide layouts\")\n            return True\n\n    def validate_no_duplicate_slide_layouts(self):\n        \"\"\"Validate that each slide has exactly one slideLayout reference.\"\"\"\n        import lxml.etree\n\n        errors = []\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Find all slideLayout relationships\n                layout_rels = [\n                    rel\n                    for rel in root.findall(\n                        f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                    )\n                    if \"slideLayout\" in rel.get(\"Type\", \"\")\n                ]\n\n                if len(layout_rels) > 1:\n                    errors.append(\n                        f\"  {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references\"\n                    )\n\n            except Exception as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(\"FAILED - Found slides with duplicate slideLayout references:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slides have exactly one slideLayout reference\")\n            return True\n\n    def validate_notes_slide_references(self):\n        \"\"\"Validate that each notesSlide file is referenced by only one slide.\"\"\"\n        import lxml.etree\n\n        errors = []\n        notes_slide_references = {}  # Track which slides reference each notesSlide\n\n        # Find all slide relationship files\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        if not slide_rels_files:\n            if self.verbose:\n                print(\"PASSED - No slide relationship files found\")\n            return True\n\n        for rels_file in slide_rels_files:\n            try:\n                # Parse the relationships file\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Find all notesSlide relationships\n                for rel in root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"notesSlide\" in rel_type:\n                        target = rel.get(\"Target\", \"\")\n                        if target:\n                            # Normalize the target path to handle relative paths\n                            normalized_target = target.replace(\"../\", \"\")\n\n                            # Track which slide references this notesSlide\n                            slide_name = rels_file.stem.replace(\n                                \".xml\", \"\"\n                            )  # e.g., \"slide1\"\n\n                            if normalized_target not in notes_slide_references:\n                                notes_slide_references[normalized_target] = []\n                            notes_slide_references[normalized_target].append(\n                                (slide_name, rels_file)\n                            )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        # Check for duplicate references\n        for target, references in notes_slide_references.items():\n            if len(references) > 1:\n                slide_names = [ref[0] for ref in references]\n                errors.append(\n                    f\"  Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}\"\n                )\n                for slide_name, rels_file in references:\n                    errors.append(f\"    - {rels_file.relative_to(self.unpacked_dir)}\")\n\n        if errors:\n            print(\n                f\"FAILED - Found {len([e for e in errors if not e.startswith('    ')])} notes slide reference validation errors:\"\n            )\n            for error in errors:\n                print(error)\n            print(\"Each slide may optionally have its own slide file.\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All notes slide references are unique\")\n            return True\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/docx/ooxml/scripts/validation/redlining.py",
    "content": "\"\"\"\nValidator for tracked changes in Word documents.\n\"\"\"\n\nimport subprocess\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\n\nclass RedliningValidator:\n    \"\"\"Validator for tracked changes in Word documents.\"\"\"\n\n    def __init__(self, unpacked_dir, original_docx, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir)\n        self.original_docx = Path(original_docx)\n        self.verbose = verbose\n        self.namespaces = {\n            \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n        }\n\n    def validate(self):\n        \"\"\"Main validation method that returns True if valid, False otherwise.\"\"\"\n        # Verify unpacked directory exists and has correct structure\n        modified_file = self.unpacked_dir / \"word\" / \"document.xml\"\n        if not modified_file.exists():\n            print(f\"FAILED - Modified document.xml not found at {modified_file}\")\n            return False\n\n        # First, check if there are any tracked changes by Claude to validate\n        try:\n            import xml.etree.ElementTree as ET\n\n            tree = ET.parse(modified_file)\n            root = tree.getroot()\n\n            # Check for w:del or w:ins tags authored by Claude\n            del_elements = root.findall(\".//w:del\", self.namespaces)\n            ins_elements = root.findall(\".//w:ins\", self.namespaces)\n\n            # Filter to only include changes by Claude\n            claude_del_elements = [\n                elem\n                for elem in del_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == \"Claude\"\n            ]\n            claude_ins_elements = [\n                elem\n                for elem in ins_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == \"Claude\"\n            ]\n\n            # Redlining validation is only needed if tracked changes by Claude have been used.\n            if not claude_del_elements and not claude_ins_elements:\n                if self.verbose:\n                    print(\"PASSED - No tracked changes by Claude found.\")\n                return True\n\n        except Exception:\n            # If we can't parse the XML, continue with full validation\n            pass\n\n        # Create temporary directory for unpacking original docx\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            # Unpack original docx\n            try:\n                with zipfile.ZipFile(self.original_docx, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_path)\n            except Exception as e:\n                print(f\"FAILED - Error unpacking original docx: {e}\")\n                return False\n\n            original_file = temp_path / \"word\" / \"document.xml\"\n            if not original_file.exists():\n                print(\n                    f\"FAILED - Original document.xml not found in {self.original_docx}\"\n                )\n                return False\n\n            # Parse both XML files using xml.etree.ElementTree for redlining validation\n            try:\n                import xml.etree.ElementTree as ET\n\n                modified_tree = ET.parse(modified_file)\n                modified_root = modified_tree.getroot()\n                original_tree = ET.parse(original_file)\n                original_root = original_tree.getroot()\n            except ET.ParseError as e:\n                print(f\"FAILED - Error parsing XML files: {e}\")\n                return False\n\n            # Remove Claude's tracked changes from both documents\n            self._remove_claude_tracked_changes(original_root)\n            self._remove_claude_tracked_changes(modified_root)\n\n            # Extract and compare text content\n            modified_text = self._extract_text_content(modified_root)\n            original_text = self._extract_text_content(original_root)\n\n            if modified_text != original_text:\n                # Show detailed character-level differences for each paragraph\n                error_message = self._generate_detailed_diff(\n                    original_text, modified_text\n                )\n                print(error_message)\n                return False\n\n            if self.verbose:\n                print(\"PASSED - All changes by Claude are properly tracked\")\n            return True\n\n    def _generate_detailed_diff(self, original_text, modified_text):\n        \"\"\"Generate detailed word-level differences using git word diff.\"\"\"\n        error_parts = [\n            \"FAILED - Document text doesn't match after removing Claude's tracked changes\",\n            \"\",\n            \"Likely causes:\",\n            \"  1. Modified text inside another author's <w:ins> or <w:del> tags\",\n            \"  2. Made edits without proper tracked changes\",\n            \"  3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion\",\n            \"\",\n            \"For pre-redlined documents, use correct patterns:\",\n            \"  - To reject another's INSERTION: Nest <w:del> inside their <w:ins>\",\n            \"  - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>\",\n            \"\",\n        ]\n\n        # Show git word diff\n        git_diff = self._get_git_word_diff(original_text, modified_text)\n        if git_diff:\n            error_parts.extend([\"Differences:\", \"============\", git_diff])\n        else:\n            error_parts.append(\"Unable to generate word diff (git not available)\")\n\n        return \"\\n\".join(error_parts)\n\n    def _get_git_word_diff(self, original_text, modified_text):\n        \"\"\"Generate word diff using git with character-level precision.\"\"\"\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                temp_path = Path(temp_dir)\n\n                # Create two files\n                original_file = temp_path / \"original.txt\"\n                modified_file = temp_path / \"modified.txt\"\n\n                original_file.write_text(original_text, encoding=\"utf-8\")\n                modified_file.write_text(modified_text, encoding=\"utf-8\")\n\n                # Try character-level diff first for precise differences\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"--word-diff-regex=.\",  # Character-by-character diff\n                        \"-U0\",  # Zero lines of context - show only changed lines\n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    # Clean up the output - remove git diff header lines\n                    lines = result.stdout.split(\"\\n\")\n                    # Skip the header lines (diff --git, index, +++, ---, @@)\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n\n                    if content_lines:\n                        return \"\\n\".join(content_lines)\n\n                # Fallback to word-level diff if character-level is too verbose\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"-U0\",  # Zero lines of context\n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n                    return \"\\n\".join(content_lines)\n\n        except (subprocess.CalledProcessError, FileNotFoundError, Exception):\n            # Git not available or other error, return None to use fallback\n            pass\n\n        return None\n\n    def _remove_claude_tracked_changes(self, root):\n        \"\"\"Remove tracked changes authored by Claude from the XML root.\"\"\"\n        ins_tag = f\"{{{self.namespaces['w']}}}ins\"\n        del_tag = f\"{{{self.namespaces['w']}}}del\"\n        author_attr = f\"{{{self.namespaces['w']}}}author\"\n\n        # Remove w:ins elements\n        for parent in root.iter():\n            to_remove = []\n            for child in parent:\n                if child.tag == ins_tag and child.get(author_attr) == \"Claude\":\n                    to_remove.append(child)\n            for elem in to_remove:\n                parent.remove(elem)\n\n        # Unwrap content in w:del elements where author is \"Claude\"\n        deltext_tag = f\"{{{self.namespaces['w']}}}delText\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        for parent in root.iter():\n            to_process = []\n            for child in parent:\n                if child.tag == del_tag and child.get(author_attr) == \"Claude\":\n                    to_process.append((child, list(parent).index(child)))\n\n            # Process in reverse order to maintain indices\n            for del_elem, del_index in reversed(to_process):\n                # Convert w:delText to w:t before moving\n                for elem in del_elem.iter():\n                    if elem.tag == deltext_tag:\n                        elem.tag = t_tag\n\n                # Move all children of w:del to its parent before removing w:del\n                for child in reversed(list(del_elem)):\n                    parent.insert(del_index, child)\n                parent.remove(del_elem)\n\n    def _extract_text_content(self, root):\n        \"\"\"Extract text content from Word XML, preserving paragraph structure.\n\n        Empty paragraphs are skipped to avoid false positives when tracked\n        insertions add only structural elements without text content.\n        \"\"\"\n        p_tag = f\"{{{self.namespaces['w']}}}p\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        paragraphs = []\n        for p_elem in root.findall(f\".//{p_tag}\"):\n            # Get all text elements within this paragraph\n            text_parts = []\n            for t_elem in p_elem.findall(f\".//{t_tag}\"):\n                if t_elem.text:\n                    text_parts.append(t_elem.text)\n            paragraph_text = \"\".join(text_parts)\n            # Skip empty paragraphs - they don't affect content validation\n            if paragraph_text:\n                paragraphs.append(paragraph_text)\n\n        return \"\\n\".join(paragraphs)\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/docx/ooxml.md",
    "content": "# Office Open XML Technical Reference\n\n**Important: Read this entire document before starting.** This document covers:\n- [Technical Guidelines](#technical-guidelines) - Schema compliance rules and validation requirements\n- [Document Content Patterns](#document-content-patterns) - XML patterns for headings, lists, tables, formatting, etc.\n- [Document Library (Python)](#document-library-python) - Recommended approach for OOXML manipulation with automatic infrastructure setup\n- [Tracked Changes (Redlining)](#tracked-changes-redlining) - XML patterns for implementing tracked changes\n\n## Technical Guidelines\n\n### Schema Compliance\n- **Element ordering in `<w:pPr>`**: `<w:pStyle>`, `<w:numPr>`, `<w:spacing>`, `<w:ind>`, `<w:jc>`\n- **Whitespace**: Add `xml:space='preserve'` to `<w:t>` elements with leading/trailing spaces\n- **Unicode**: Escape characters in ASCII content: `\"` becomes `&#8220;`\n  - **Character encoding reference**: Curly quotes `\"\"` become `&#8220;&#8221;`, apostrophe `'` becomes `&#8217;`, em-dash `—` becomes `&#8212;`\n- **Tracked changes**: Use `<w:del>` and `<w:ins>` tags with `w:author=\"Claude\"` outside `<w:r>` elements\n  - **Critical**: `<w:ins>` closes with `</w:ins>`, `<w:del>` closes with `</w:del>` - never mix\n  - **RSIDs must be 8-digit hex**: Use values like `00AB1234` (only 0-9, A-F characters)\n  - **trackRevisions placement**: Add `<w:trackRevisions/>` after `<w:proofState>` in settings.xml\n- **Images**: Add to `word/media/`, reference in `document.xml`, set dimensions to prevent overflow\n\n## Document Content Patterns\n\n### Basic Structure\n```xml\n<w:p>\n  <w:r><w:t>Text content</w:t></w:r>\n</w:p>\n```\n\n### Headings and Styles\n```xml\n<w:p>\n  <w:pPr>\n    <w:pStyle w:val=\"Title\"/>\n    <w:jc w:val=\"center\"/>\n  </w:pPr>\n  <w:r><w:t>Document Title</w:t></w:r>\n</w:p>\n\n<w:p>\n  <w:pPr><w:pStyle w:val=\"Heading2\"/></w:pPr>\n  <w:r><w:t>Section Heading</w:t></w:r>\n</w:p>\n```\n\n### Text Formatting\n```xml\n<!-- Bold -->\n<w:r><w:rPr><w:b/><w:bCs/></w:rPr><w:t>Bold</w:t></w:r>\n<!-- Italic -->\n<w:r><w:rPr><w:i/><w:iCs/></w:rPr><w:t>Italic</w:t></w:r>\n<!-- Underline -->\n<w:r><w:rPr><w:u w:val=\"single\"/></w:rPr><w:t>Underlined</w:t></w:r>\n<!-- Highlight -->\n<w:r><w:rPr><w:highlight w:val=\"yellow\"/></w:rPr><w:t>Highlighted</w:t></w:r>\n```\n\n### Lists\n```xml\n<!-- Numbered list -->\n<w:p>\n  <w:pPr>\n    <w:pStyle w:val=\"ListParagraph\"/>\n    <w:numPr><w:ilvl w:val=\"0\"/><w:numId w:val=\"1\"/></w:numPr>\n    <w:spacing w:before=\"240\"/>\n  </w:pPr>\n  <w:r><w:t>First item</w:t></w:r>\n</w:p>\n\n<!-- Restart numbered list at 1 - use different numId -->\n<w:p>\n  <w:pPr>\n    <w:pStyle w:val=\"ListParagraph\"/>\n    <w:numPr><w:ilvl w:val=\"0\"/><w:numId w:val=\"2\"/></w:numPr>\n    <w:spacing w:before=\"240\"/>\n  </w:pPr>\n  <w:r><w:t>New list item 1</w:t></w:r>\n</w:p>\n\n<!-- Bullet list (level 2) -->\n<w:p>\n  <w:pPr>\n    <w:pStyle w:val=\"ListParagraph\"/>\n    <w:numPr><w:ilvl w:val=\"1\"/><w:numId w:val=\"1\"/></w:numPr>\n    <w:spacing w:before=\"240\"/>\n    <w:ind w:left=\"900\"/>\n  </w:pPr>\n  <w:r><w:t>Bullet item</w:t></w:r>\n</w:p>\n```\n\n### Tables\n```xml\n<w:tbl>\n  <w:tblPr>\n    <w:tblStyle w:val=\"TableGrid\"/>\n    <w:tblW w:w=\"0\" w:type=\"auto\"/>\n  </w:tblPr>\n  <w:tblGrid>\n    <w:gridCol w:w=\"4675\"/><w:gridCol w:w=\"4675\"/>\n  </w:tblGrid>\n  <w:tr>\n    <w:tc>\n      <w:tcPr><w:tcW w:w=\"4675\" w:type=\"dxa\"/></w:tcPr>\n      <w:p><w:r><w:t>Cell 1</w:t></w:r></w:p>\n    </w:tc>\n    <w:tc>\n      <w:tcPr><w:tcW w:w=\"4675\" w:type=\"dxa\"/></w:tcPr>\n      <w:p><w:r><w:t>Cell 2</w:t></w:r></w:p>\n    </w:tc>\n  </w:tr>\n</w:tbl>\n```\n\n### Layout\n```xml\n<!-- Page break before new section (common pattern) -->\n<w:p>\n  <w:r>\n    <w:br w:type=\"page\"/>\n  </w:r>\n</w:p>\n<w:p>\n  <w:pPr>\n    <w:pStyle w:val=\"Heading1\"/>\n  </w:pPr>\n  <w:r>\n    <w:t>New Section Title</w:t>\n  </w:r>\n</w:p>\n\n<!-- Centered paragraph -->\n<w:p>\n  <w:pPr>\n    <w:spacing w:before=\"240\" w:after=\"0\"/>\n    <w:jc w:val=\"center\"/>\n  </w:pPr>\n  <w:r><w:t>Centered text</w:t></w:r>\n</w:p>\n\n<!-- Font change - paragraph level (applies to all runs) -->\n<w:p>\n  <w:pPr>\n    <w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\"/></w:rPr>\n  </w:pPr>\n  <w:r><w:t>Monospace text</w:t></w:r>\n</w:p>\n\n<!-- Font change - run level (specific to this text) -->\n<w:p>\n  <w:r>\n    <w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\"/></w:rPr>\n    <w:t>This text is Courier New</w:t>\n  </w:r>\n  <w:r><w:t> and this text uses default font</w:t></w:r>\n</w:p>\n```\n\n## File Updates\n\nWhen adding content, update these files:\n\n**`word/_rels/document.xml.rels`:**\n```xml\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>\n<Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image1.png\"/>\n```\n\n**`[Content_Types].xml`:**\n```xml\n<Default Extension=\"png\" ContentType=\"image/png\"/>\n<Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>\n```\n\n### Images\n**CRITICAL**: Calculate dimensions to prevent page overflow and maintain aspect ratio.\n\n```xml\n<!-- Minimal required structure -->\n<w:p>\n  <w:r>\n    <w:drawing>\n      <wp:inline>\n        <wp:extent cx=\"2743200\" cy=\"1828800\"/>\n        <wp:docPr id=\"1\" name=\"Picture 1\"/>\n        <a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">\n          <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n            <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n              <pic:nvPicPr>\n                <pic:cNvPr id=\"0\" name=\"image1.png\"/>\n                <pic:cNvPicPr/>\n              </pic:nvPicPr>\n              <pic:blipFill>\n                <a:blip r:embed=\"rId5\"/>\n                <!-- Add for stretch fill with aspect ratio preservation -->\n                <a:stretch>\n                  <a:fillRect/>\n                </a:stretch>\n              </pic:blipFill>\n              <pic:spPr>\n                <a:xfrm>\n                  <a:ext cx=\"2743200\" cy=\"1828800\"/>\n                </a:xfrm>\n                <a:prstGeom prst=\"rect\"/>\n              </pic:spPr>\n            </pic:pic>\n          </a:graphicData>\n        </a:graphic>\n      </wp:inline>\n    </w:drawing>\n  </w:r>\n</w:p>\n```\n\n### Links (Hyperlinks)\n\n**IMPORTANT**: All hyperlinks (both internal and external) require the Hyperlink style to be defined in styles.xml. Without this style, links will look like regular text instead of blue underlined clickable links.\n\n**External Links:**\n```xml\n<!-- In document.xml -->\n<w:hyperlink r:id=\"rId5\">\n  <w:r>\n    <w:rPr><w:rStyle w:val=\"Hyperlink\"/></w:rPr>\n    <w:t>Link Text</w:t>\n  </w:r>\n</w:hyperlink>\n\n<!-- In word/_rels/document.xml.rels -->\n<Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" \n              Target=\"https://www.example.com/\" TargetMode=\"External\"/>\n```\n\n**Internal Links:**\n\n```xml\n<!-- Link to bookmark -->\n<w:hyperlink w:anchor=\"myBookmark\">\n  <w:r>\n    <w:rPr><w:rStyle w:val=\"Hyperlink\"/></w:rPr>\n    <w:t>Link Text</w:t>\n  </w:r>\n</w:hyperlink>\n\n<!-- Bookmark target -->\n<w:bookmarkStart w:id=\"0\" w:name=\"myBookmark\"/>\n<w:r><w:t>Target content</w:t></w:r>\n<w:bookmarkEnd w:id=\"0\"/>\n```\n\n**Hyperlink Style (required in styles.xml):**\n```xml\n<w:style w:type=\"character\" w:styleId=\"Hyperlink\">\n  <w:name w:val=\"Hyperlink\"/>\n  <w:basedOn w:val=\"DefaultParagraphFont\"/>\n  <w:uiPriority w:val=\"99\"/>\n  <w:unhideWhenUsed/>\n  <w:rPr>\n    <w:color w:val=\"467886\" w:themeColor=\"hyperlink\"/>\n    <w:u w:val=\"single\"/>\n  </w:rPr>\n</w:style>\n```\n\n## Document Library (Python)\n\nUse the Document class from `scripts/document.py` for all tracked changes and comments. It automatically handles infrastructure setup (people.xml, RSIDs, settings.xml, comment files, relationships, content types). Only use direct XML manipulation for complex scenarios not supported by the library.\n\n**Working with Unicode and Entities:**\n- **Searching**: Both entity notation and Unicode characters work - `contains=\"&#8220;Company\"` and `contains=\"\\u201cCompany\"` find the same text\n- **Replacing**: Use either entities (`&#8220;`) or Unicode (`\\u201c`) - both work and will be converted appropriately based on the file's encoding (ascii → entities, utf-8 → Unicode)\n\n### Initialization\n\n**Find the docx skill root** (directory containing `scripts/` and `ooxml/`):\n```bash\n# Search for document.py to locate the skill root\n# Note: /mnt/skills is used here as an example; check your context for the actual location\nfind /mnt/skills -name \"document.py\" -path \"*/docx/scripts/*\" 2>/dev/null | head -1\n# Example output: /mnt/skills/docx/scripts/document.py\n# Skill root is: /mnt/skills/docx\n```\n\n**Run your script with PYTHONPATH** set to the docx skill root:\n```bash\nPYTHONPATH=/mnt/skills/docx python your_script.py\n```\n\n**In your script**, import from the skill root:\n```python\nfrom scripts.document import Document, DocxXMLEditor\n\n# Basic initialization (automatically creates temp copy and sets up infrastructure)\ndoc = Document('unpacked')\n\n# Customize author and initials\ndoc = Document('unpacked', author=\"John Doe\", initials=\"JD\")\n\n# Enable track revisions mode\ndoc = Document('unpacked', track_revisions=True)\n\n# Specify custom RSID (auto-generated if not provided)\ndoc = Document('unpacked', rsid=\"07DC5ECB\")\n```\n\n### Creating Tracked Changes\n\n**CRITICAL**: Only mark text that actually changes. Keep ALL unchanged text outside `<w:del>`/`<w:ins>` tags. Marking unchanged text makes edits unprofessional and harder to review.\n\n**Attribute Handling**: The Document class auto-injects attributes (w:id, w:date, w:rsidR, w:rsidDel, w16du:dateUtc, xml:space) into new elements. When preserving unchanged text from the original document, copy the original `<w:r>` element with its existing attributes to maintain document integrity.\n\n**Method Selection Guide**:\n- **Adding your own changes to regular text**: Use `replace_node()` with `<w:del>`/`<w:ins>` tags, or `suggest_deletion()` for removing entire `<w:r>` or `<w:p>` elements\n- **Partially modifying another author's tracked change**: Use `replace_node()` to nest your changes inside their `<w:ins>`/`<w:del>`\n- **Completely rejecting another author's insertion**: Use `revert_insertion()` on the `<w:ins>` element (NOT `suggest_deletion()`)\n- **Completely rejecting another author's deletion**: Use `revert_deletion()` on the `<w:del>` element to restore deleted content using tracked changes\n\n```python\n# Minimal edit - change one word: \"The report is monthly\" → \"The report is quarterly\"\n# Original: <w:r w:rsidR=\"00AB12CD\"><w:rPr><w:rFonts w:ascii=\"Calibri\"/></w:rPr><w:t>The report is monthly</w:t></w:r>\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"The report is monthly\")\nrpr = tags[0].toxml() if (tags := node.getElementsByTagName(\"w:rPr\")) else \"\"\nreplacement = f'<w:r w:rsidR=\"00AB12CD\">{rpr}<w:t>The report is </w:t></w:r><w:del><w:r>{rpr}<w:delText>monthly</w:delText></w:r></w:del><w:ins><w:r>{rpr}<w:t>quarterly</w:t></w:r></w:ins>'\ndoc[\"word/document.xml\"].replace_node(node, replacement)\n\n# Minimal edit - change number: \"within 30 days\" → \"within 45 days\"\n# Original: <w:r w:rsidR=\"00XYZ789\"><w:rPr><w:rFonts w:ascii=\"Calibri\"/></w:rPr><w:t>within 30 days</w:t></w:r>\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"within 30 days\")\nrpr = tags[0].toxml() if (tags := node.getElementsByTagName(\"w:rPr\")) else \"\"\nreplacement = f'<w:r w:rsidR=\"00XYZ789\">{rpr}<w:t>within </w:t></w:r><w:del><w:r>{rpr}<w:delText>30</w:delText></w:r></w:del><w:ins><w:r>{rpr}<w:t>45</w:t></w:r></w:ins><w:r w:rsidR=\"00XYZ789\">{rpr}<w:t> days</w:t></w:r>'\ndoc[\"word/document.xml\"].replace_node(node, replacement)\n\n# Complete replacement - preserve formatting even when replacing all text\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"apple\")\nrpr = tags[0].toxml() if (tags := node.getElementsByTagName(\"w:rPr\")) else \"\"\nreplacement = f'<w:del><w:r>{rpr}<w:delText>apple</w:delText></w:r></w:del><w:ins><w:r>{rpr}<w:t>banana orange</w:t></w:r></w:ins>'\ndoc[\"word/document.xml\"].replace_node(node, replacement)\n\n# Insert new content (no attributes needed - auto-injected)\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"existing text\")\ndoc[\"word/document.xml\"].insert_after(node, '<w:ins><w:r><w:t>new text</w:t></w:r></w:ins>')\n\n# Partially delete another author's insertion\n# Original: <w:ins w:author=\"Jane Smith\" w:date=\"...\"><w:r><w:t>quarterly financial report</w:t></w:r></w:ins>\n# Goal: Delete only \"financial\" to make it \"quarterly report\"\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:ins\", attrs={\"w:id\": \"5\"})\n# IMPORTANT: Preserve w:author=\"Jane Smith\" on the outer <w:ins> to maintain authorship\nreplacement = '''<w:ins w:author=\"Jane Smith\" w:date=\"2025-01-15T10:00:00Z\">\n  <w:r><w:t>quarterly </w:t></w:r>\n  <w:del><w:r><w:delText>financial </w:delText></w:r></w:del>\n  <w:r><w:t>report</w:t></w:r>\n</w:ins>'''\ndoc[\"word/document.xml\"].replace_node(node, replacement)\n\n# Change part of another author's insertion\n# Original: <w:ins w:author=\"Jane Smith\"><w:r><w:t>in silence, safe and sound</w:t></w:r></w:ins>\n# Goal: Change \"safe and sound\" to \"soft and unbound\"\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:ins\", attrs={\"w:id\": \"8\"})\nreplacement = f'''<w:ins w:author=\"Jane Smith\" w:date=\"2025-01-15T10:00:00Z\">\n  <w:r><w:t>in silence, </w:t></w:r>\n</w:ins>\n<w:ins>\n  <w:r><w:t>soft and unbound</w:t></w:r>\n</w:ins>\n<w:ins w:author=\"Jane Smith\" w:date=\"2025-01-15T10:00:00Z\">\n  <w:del><w:r><w:delText>safe and sound</w:delText></w:r></w:del>\n</w:ins>'''\ndoc[\"word/document.xml\"].replace_node(node, replacement)\n\n# Delete entire run (use only when deleting all content; use replace_node for partial deletions)\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"text to delete\")\ndoc[\"word/document.xml\"].suggest_deletion(node)\n\n# Delete entire paragraph (in-place, handles both regular and numbered list paragraphs)\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"paragraph to delete\")\ndoc[\"word/document.xml\"].suggest_deletion(para)\n\n# Add new numbered list item\ntarget_para = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"existing list item\")\npPr = tags[0].toxml() if (tags := target_para.getElementsByTagName(\"w:pPr\")) else \"\"\nnew_item = f'<w:p>{pPr}<w:r><w:t>New item</w:t></w:r></w:p>'\ntracked_para = DocxXMLEditor.suggest_paragraph(new_item)\ndoc[\"word/document.xml\"].insert_after(target_para, tracked_para)\n# Optional: add spacing paragraph before content for better visual separation\n# spacing = DocxXMLEditor.suggest_paragraph('<w:p><w:pPr><w:pStyle w:val=\"ListParagraph\"/></w:pPr></w:p>')\n# doc[\"word/document.xml\"].insert_after(target_para, spacing + tracked_para)\n```\n\n### Adding Comments\n\n```python\n# Add comment spanning two existing tracked changes\n# Note: w:id is auto-generated. Only search by w:id if you know it from XML inspection\nstart_node = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"1\"})\nend_node = doc[\"word/document.xml\"].get_node(tag=\"w:ins\", attrs={\"w:id\": \"2\"})\ndoc.add_comment(start=start_node, end=end_node, text=\"Explanation of this change\")\n\n# Add comment on a paragraph\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"paragraph text\")\ndoc.add_comment(start=para, end=para, text=\"Comment on this paragraph\")\n\n# Add comment on newly created tracked change\n# First create the tracked change\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"old\")\nnew_nodes = doc[\"word/document.xml\"].replace_node(\n    node,\n    '<w:del><w:r><w:delText>old</w:delText></w:r></w:del><w:ins><w:r><w:t>new</w:t></w:r></w:ins>'\n)\n# Then add comment on the newly created elements\n# new_nodes[0] is the <w:del>, new_nodes[1] is the <w:ins>\ndoc.add_comment(start=new_nodes[0], end=new_nodes[1], text=\"Changed old to new per requirements\")\n\n# Reply to existing comment\ndoc.reply_to_comment(parent_comment_id=0, text=\"I agree with this change\")\n```\n\n### Rejecting Tracked Changes\n\n**IMPORTANT**: Use `revert_insertion()` to reject insertions and `revert_deletion()` to restore deletions using tracked changes. Use `suggest_deletion()` only for regular unmarked content.\n\n```python\n# Reject insertion (wraps it in deletion)\n# Use this when another author inserted text that you want to delete\nins = doc[\"word/document.xml\"].get_node(tag=\"w:ins\", attrs={\"w:id\": \"5\"})\nnodes = doc[\"word/document.xml\"].revert_insertion(ins)  # Returns [ins]\n\n# Reject deletion (creates insertion to restore deleted content)\n# Use this when another author deleted text that you want to restore\ndel_elem = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"3\"})\nnodes = doc[\"word/document.xml\"].revert_deletion(del_elem)  # Returns [del_elem, new_ins]\n\n# Reject all insertions in a paragraph\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"paragraph text\")\nnodes = doc[\"word/document.xml\"].revert_insertion(para)  # Returns [para]\n\n# Reject all deletions in a paragraph\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"paragraph text\")\nnodes = doc[\"word/document.xml\"].revert_deletion(para)  # Returns [para]\n```\n\n### Inserting Images\n\n**CRITICAL**: The Document class works with a temporary copy at `doc.unpacked_path`. Always copy images to this temp directory, not the original unpacked folder.\n\n```python\nfrom PIL import Image\nimport shutil, os\n\n# Initialize document first\ndoc = Document('unpacked')\n\n# Copy image and calculate full-width dimensions with aspect ratio\nmedia_dir = os.path.join(doc.unpacked_path, 'word/media')\nos.makedirs(media_dir, exist_ok=True)\nshutil.copy('image.png', os.path.join(media_dir, 'image1.png'))\nimg = Image.open(os.path.join(media_dir, 'image1.png'))\nwidth_emus = int(6.5 * 914400)  # 6.5\" usable width, 914400 EMUs/inch\nheight_emus = int(width_emus * img.size[1] / img.size[0])\n\n# Add relationship and content type\nrels_editor = doc['word/_rels/document.xml.rels']\nnext_rid = rels_editor.get_next_rid()\nrels_editor.append_to(rels_editor.dom.documentElement,\n    f'<Relationship Id=\"{next_rid}\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image1.png\"/>')\ndoc['[Content_Types].xml'].append_to(doc['[Content_Types].xml'].dom.documentElement,\n    '<Default Extension=\"png\" ContentType=\"image/png\"/>')\n\n# Insert image\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=100)\ndoc[\"word/document.xml\"].insert_after(node, f'''<w:p>\n  <w:r>\n    <w:drawing>\n      <wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">\n        <wp:extent cx=\"{width_emus}\" cy=\"{height_emus}\"/>\n        <wp:docPr id=\"1\" name=\"Picture 1\"/>\n        <a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">\n          <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n            <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n              <pic:nvPicPr><pic:cNvPr id=\"1\" name=\"image1.png\"/><pic:cNvPicPr/></pic:nvPicPr>\n              <pic:blipFill><a:blip r:embed=\"{next_rid}\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>\n              <pic:spPr><a:xfrm><a:ext cx=\"{width_emus}\" cy=\"{height_emus}\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr>\n            </pic:pic>\n          </a:graphicData>\n        </a:graphic>\n      </wp:inline>\n    </w:drawing>\n  </w:r>\n</w:p>''')\n```\n\n### Getting Nodes\n\n```python\n# By text content\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"specific text\")\n\n# By line range\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=range(100, 150))\n\n# By attributes\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"1\"})\n\n# By exact line number (must be line number where tag opens)\npara = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=42)\n\n# Combine filters\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", line_number=range(40, 60), contains=\"text\")\n\n# Disambiguate when text appears multiple times - add line_number range\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", contains=\"Section\", line_number=range(2400, 2500))\n```\n\n### Saving\n\n```python\n# Save with automatic validation (copies back to original directory)\ndoc.save()  # Validates by default, raises error if validation fails\n\n# Save to different location\ndoc.save('modified-unpacked')\n\n# Skip validation (debugging only - needing this in production indicates XML issues)\ndoc.save(validate=False)\n```\n\n### Direct DOM Manipulation\n\nFor complex scenarios not covered by the library:\n\n```python\n# Access any XML file\neditor = doc[\"word/document.xml\"]\neditor = doc[\"word/comments.xml\"]\n\n# Direct DOM access (defusedxml.minidom.Document)\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=5)\nparent = node.parentNode\nparent.removeChild(node)\nparent.appendChild(node)  # Move to end\n\n# General document manipulation (without tracked changes)\nold_node = doc[\"word/document.xml\"].get_node(tag=\"w:p\", contains=\"original text\")\ndoc[\"word/document.xml\"].replace_node(old_node, \"<w:p><w:r><w:t>replacement text</w:t></w:r></w:p>\")\n\n# Multiple insertions - use return value to maintain order\nnode = doc[\"word/document.xml\"].get_node(tag=\"w:r\", line_number=100)\nnodes = doc[\"word/document.xml\"].insert_after(node, \"<w:r><w:t>A</w:t></w:r>\")\nnodes = doc[\"word/document.xml\"].insert_after(nodes[-1], \"<w:r><w:t>B</w:t></w:r>\")\nnodes = doc[\"word/document.xml\"].insert_after(nodes[-1], \"<w:r><w:t>C</w:t></w:r>\")\n# Results in: original_node, A, B, C\n```\n\n## Tracked Changes (Redlining)\n\n**Use the Document class above for all tracked changes.** The patterns below are for reference when constructing replacement XML strings.\n\n### Validation Rules\nThe validator checks that the document text matches the original after reverting Claude's changes. This means:\n- **NEVER modify text inside another author's `<w:ins>` or `<w:del>` tags**\n- **ALWAYS use nested deletions** to remove another author's insertions\n- **Every edit must be properly tracked** with `<w:ins>` or `<w:del>` tags\n\n### Tracked Change Patterns\n\n**CRITICAL RULES**:\n1. Never modify the content inside another author's tracked changes. Always use nested deletions.\n2. **XML Structure**: Always place `<w:del>` and `<w:ins>` at paragraph level containing complete `<w:r>` elements. Never nest inside `<w:r>` elements - this creates invalid XML that breaks document processing.\n\n**Text Insertion:**\n```xml\n<w:ins w:id=\"1\" w:author=\"Claude\" w:date=\"2025-07-30T23:05:00Z\" w16du:dateUtc=\"2025-07-31T06:05:00Z\">\n  <w:r w:rsidR=\"00792858\">\n    <w:t>inserted text</w:t>\n  </w:r>\n</w:ins>\n```\n\n**Text Deletion:**\n```xml\n<w:del w:id=\"2\" w:author=\"Claude\" w:date=\"2025-07-30T23:05:00Z\" w16du:dateUtc=\"2025-07-31T06:05:00Z\">\n  <w:r w:rsidDel=\"00792858\">\n    <w:delText>deleted text</w:delText>\n  </w:r>\n</w:del>\n```\n\n**Deleting Another Author's Insertion (MUST use nested structure):**\n```xml\n<!-- Nest deletion inside the original insertion -->\n<w:ins w:author=\"Jane Smith\" w:id=\"16\">\n  <w:del w:author=\"Claude\" w:id=\"40\">\n    <w:r><w:delText>monthly</w:delText></w:r>\n  </w:del>\n</w:ins>\n<w:ins w:author=\"Claude\" w:id=\"41\">\n  <w:r><w:t>weekly</w:t></w:r>\n</w:ins>\n```\n\n**Restoring Another Author's Deletion:**\n```xml\n<!-- Leave their deletion unchanged, add new insertion after it -->\n<w:del w:author=\"Jane Smith\" w:id=\"50\">\n  <w:r><w:delText>within 30 days</w:delText></w:r>\n</w:del>\n<w:ins w:author=\"Claude\" w:id=\"51\">\n  <w:r><w:t>within 30 days</w:t></w:r>\n</w:ins>\n```"
  },
  {
    "path": "document-skills/docx/scripts/__init__.py",
    "content": "# Make scripts directory a package for relative imports in tests\n"
  },
  {
    "path": "document-skills/docx/scripts/document.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nLibrary for working with Word documents: comments, tracked changes, and editing.\n\nUsage:\n    from skills.docx.scripts.document import Document\n\n    # Initialize\n    doc = Document('workspace/unpacked')\n    doc = Document('workspace/unpacked', author=\"John Doe\", initials=\"JD\")\n\n    # Find nodes\n    node = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"1\"})\n    node = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=10)\n\n    # Add comments\n    doc.add_comment(start=node, end=node, text=\"Comment text\")\n    doc.reply_to_comment(parent_comment_id=0, text=\"Reply text\")\n\n    # Suggest tracked changes\n    doc[\"word/document.xml\"].suggest_deletion(node)  # Delete content\n    doc[\"word/document.xml\"].revert_insertion(ins_node)  # Reject insertion\n    doc[\"word/document.xml\"].revert_deletion(del_node)  # Reject deletion\n\n    # Save\n    doc.save()\n\"\"\"\n\nimport html\nimport random\nimport shutil\nimport tempfile\nfrom datetime import datetime, timezone\nfrom pathlib import Path\n\nfrom defusedxml import minidom\nfrom ooxml.scripts.pack import pack_document\nfrom ooxml.scripts.validation.docx import DOCXSchemaValidator\nfrom ooxml.scripts.validation.redlining import RedliningValidator\n\nfrom .utilities import XMLEditor\n\n# Path to template files\nTEMPLATE_DIR = Path(__file__).parent / \"templates\"\n\n\nclass DocxXMLEditor(XMLEditor):\n    \"\"\"XMLEditor that automatically applies RSID, author, and date to new elements.\n\n    Automatically adds attributes to elements that support them when inserting new content:\n    - w:rsidR, w:rsidRDefault, w:rsidP (for w:p and w:r elements)\n    - w:author and w:date (for w:ins, w:del, w:comment elements)\n    - w:id (for w:ins and w:del elements)\n\n    Attributes:\n        dom (defusedxml.minidom.Document): The DOM document for direct manipulation\n    \"\"\"\n\n    def __init__(\n        self, xml_path, rsid: str, author: str = \"Claude\", initials: str = \"C\"\n    ):\n        \"\"\"Initialize with required RSID and optional author.\n\n        Args:\n            xml_path: Path to XML file to edit\n            rsid: RSID to automatically apply to new elements\n            author: Author name for tracked changes and comments (default: \"Claude\")\n            initials: Author initials (default: \"C\")\n        \"\"\"\n        super().__init__(xml_path)\n        self.rsid = rsid\n        self.author = author\n        self.initials = initials\n\n    def _get_next_change_id(self):\n        \"\"\"Get the next available change ID by checking all tracked change elements.\"\"\"\n        max_id = -1\n        for tag in (\"w:ins\", \"w:del\"):\n            elements = self.dom.getElementsByTagName(tag)\n            for elem in elements:\n                change_id = elem.getAttribute(\"w:id\")\n                if change_id:\n                    try:\n                        max_id = max(max_id, int(change_id))\n                    except ValueError:\n                        pass\n        return max_id + 1\n\n    def _ensure_w16du_namespace(self):\n        \"\"\"Ensure w16du namespace is declared on the root element.\"\"\"\n        root = self.dom.documentElement\n        if not root.hasAttribute(\"xmlns:w16du\"):  # type: ignore\n            root.setAttribute(  # type: ignore\n                \"xmlns:w16du\",\n                \"http://schemas.microsoft.com/office/word/2023/wordml/word16du\",\n            )\n\n    def _ensure_w16cex_namespace(self):\n        \"\"\"Ensure w16cex namespace is declared on the root element.\"\"\"\n        root = self.dom.documentElement\n        if not root.hasAttribute(\"xmlns:w16cex\"):  # type: ignore\n            root.setAttribute(  # type: ignore\n                \"xmlns:w16cex\",\n                \"http://schemas.microsoft.com/office/word/2018/wordml/cex\",\n            )\n\n    def _ensure_w14_namespace(self):\n        \"\"\"Ensure w14 namespace is declared on the root element.\"\"\"\n        root = self.dom.documentElement\n        if not root.hasAttribute(\"xmlns:w14\"):  # type: ignore\n            root.setAttribute(  # type: ignore\n                \"xmlns:w14\",\n                \"http://schemas.microsoft.com/office/word/2010/wordml\",\n            )\n\n    def _inject_attributes_to_nodes(self, nodes):\n        \"\"\"Inject RSID, author, and date attributes into DOM nodes where applicable.\n\n        Adds attributes to elements that support them:\n        - w:r: gets w:rsidR (or w:rsidDel if inside w:del)\n        - w:p: gets w:rsidR, w:rsidRDefault, w:rsidP, w14:paraId, w14:textId\n        - w:t: gets xml:space=\"preserve\" if text has leading/trailing whitespace\n        - w:ins, w:del: get w:id, w:author, w:date, w16du:dateUtc\n        - w:comment: gets w:author, w:date, w:initials\n        - w16cex:commentExtensible: gets w16cex:dateUtc\n\n        Args:\n            nodes: List of DOM nodes to process\n        \"\"\"\n        from datetime import datetime, timezone\n\n        timestamp = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n\n        def is_inside_deletion(elem):\n            \"\"\"Check if element is inside a w:del element.\"\"\"\n            parent = elem.parentNode\n            while parent:\n                if parent.nodeType == parent.ELEMENT_NODE and parent.tagName == \"w:del\":\n                    return True\n                parent = parent.parentNode\n            return False\n\n        def add_rsid_to_p(elem):\n            if not elem.hasAttribute(\"w:rsidR\"):\n                elem.setAttribute(\"w:rsidR\", self.rsid)\n            if not elem.hasAttribute(\"w:rsidRDefault\"):\n                elem.setAttribute(\"w:rsidRDefault\", self.rsid)\n            if not elem.hasAttribute(\"w:rsidP\"):\n                elem.setAttribute(\"w:rsidP\", self.rsid)\n            # Add w14:paraId and w14:textId if not present\n            if not elem.hasAttribute(\"w14:paraId\"):\n                self._ensure_w14_namespace()\n                elem.setAttribute(\"w14:paraId\", _generate_hex_id())\n            if not elem.hasAttribute(\"w14:textId\"):\n                self._ensure_w14_namespace()\n                elem.setAttribute(\"w14:textId\", _generate_hex_id())\n\n        def add_rsid_to_r(elem):\n            # Use w:rsidDel for <w:r> inside <w:del>, otherwise w:rsidR\n            if is_inside_deletion(elem):\n                if not elem.hasAttribute(\"w:rsidDel\"):\n                    elem.setAttribute(\"w:rsidDel\", self.rsid)\n            else:\n                if not elem.hasAttribute(\"w:rsidR\"):\n                    elem.setAttribute(\"w:rsidR\", self.rsid)\n\n        def add_tracked_change_attrs(elem):\n            # Auto-assign w:id if not present\n            if not elem.hasAttribute(\"w:id\"):\n                elem.setAttribute(\"w:id\", str(self._get_next_change_id()))\n            if not elem.hasAttribute(\"w:author\"):\n                elem.setAttribute(\"w:author\", self.author)\n            if not elem.hasAttribute(\"w:date\"):\n                elem.setAttribute(\"w:date\", timestamp)\n            # Add w16du:dateUtc for tracked changes (same as w:date since we generate UTC timestamps)\n            if elem.tagName in (\"w:ins\", \"w:del\") and not elem.hasAttribute(\n                \"w16du:dateUtc\"\n            ):\n                self._ensure_w16du_namespace()\n                elem.setAttribute(\"w16du:dateUtc\", timestamp)\n\n        def add_comment_attrs(elem):\n            if not elem.hasAttribute(\"w:author\"):\n                elem.setAttribute(\"w:author\", self.author)\n            if not elem.hasAttribute(\"w:date\"):\n                elem.setAttribute(\"w:date\", timestamp)\n            if not elem.hasAttribute(\"w:initials\"):\n                elem.setAttribute(\"w:initials\", self.initials)\n\n        def add_comment_extensible_date(elem):\n            # Add w16cex:dateUtc for comment extensible elements\n            if not elem.hasAttribute(\"w16cex:dateUtc\"):\n                self._ensure_w16cex_namespace()\n                elem.setAttribute(\"w16cex:dateUtc\", timestamp)\n\n        def add_xml_space_to_t(elem):\n            # Add xml:space=\"preserve\" to w:t if text has leading/trailing whitespace\n            if (\n                elem.firstChild\n                and elem.firstChild.nodeType == elem.firstChild.TEXT_NODE\n            ):\n                text = elem.firstChild.data\n                if text and (text[0].isspace() or text[-1].isspace()):\n                    if not elem.hasAttribute(\"xml:space\"):\n                        elem.setAttribute(\"xml:space\", \"preserve\")\n\n        for node in nodes:\n            if node.nodeType != node.ELEMENT_NODE:\n                continue\n\n            # Handle the node itself\n            if node.tagName == \"w:p\":\n                add_rsid_to_p(node)\n            elif node.tagName == \"w:r\":\n                add_rsid_to_r(node)\n            elif node.tagName == \"w:t\":\n                add_xml_space_to_t(node)\n            elif node.tagName in (\"w:ins\", \"w:del\"):\n                add_tracked_change_attrs(node)\n            elif node.tagName == \"w:comment\":\n                add_comment_attrs(node)\n            elif node.tagName == \"w16cex:commentExtensible\":\n                add_comment_extensible_date(node)\n\n            # Process descendants (getElementsByTagName doesn't return the element itself)\n            for elem in node.getElementsByTagName(\"w:p\"):\n                add_rsid_to_p(elem)\n            for elem in node.getElementsByTagName(\"w:r\"):\n                add_rsid_to_r(elem)\n            for elem in node.getElementsByTagName(\"w:t\"):\n                add_xml_space_to_t(elem)\n            for tag in (\"w:ins\", \"w:del\"):\n                for elem in node.getElementsByTagName(tag):\n                    add_tracked_change_attrs(elem)\n            for elem in node.getElementsByTagName(\"w:comment\"):\n                add_comment_attrs(elem)\n            for elem in node.getElementsByTagName(\"w16cex:commentExtensible\"):\n                add_comment_extensible_date(elem)\n\n    def replace_node(self, elem, new_content):\n        \"\"\"Replace node with automatic attribute injection.\"\"\"\n        nodes = super().replace_node(elem, new_content)\n        self._inject_attributes_to_nodes(nodes)\n        return nodes\n\n    def insert_after(self, elem, xml_content):\n        \"\"\"Insert after with automatic attribute injection.\"\"\"\n        nodes = super().insert_after(elem, xml_content)\n        self._inject_attributes_to_nodes(nodes)\n        return nodes\n\n    def insert_before(self, elem, xml_content):\n        \"\"\"Insert before with automatic attribute injection.\"\"\"\n        nodes = super().insert_before(elem, xml_content)\n        self._inject_attributes_to_nodes(nodes)\n        return nodes\n\n    def append_to(self, elem, xml_content):\n        \"\"\"Append to with automatic attribute injection.\"\"\"\n        nodes = super().append_to(elem, xml_content)\n        self._inject_attributes_to_nodes(nodes)\n        return nodes\n\n    def revert_insertion(self, elem):\n        \"\"\"Reject an insertion by wrapping its content in a deletion.\n\n        Wraps all runs inside w:ins in w:del, converting w:t to w:delText.\n        Can process a single w:ins element or a container element with multiple w:ins.\n\n        Args:\n            elem: Element to process (w:ins, w:p, w:body, etc.)\n\n        Returns:\n            list: List containing the processed element(s)\n\n        Raises:\n            ValueError: If the element contains no w:ins elements\n\n        Example:\n            # Reject a single insertion\n            ins = doc[\"word/document.xml\"].get_node(tag=\"w:ins\", attrs={\"w:id\": \"5\"})\n            doc[\"word/document.xml\"].revert_insertion(ins)\n\n            # Reject all insertions in a paragraph\n            para = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=42)\n            doc[\"word/document.xml\"].revert_insertion(para)\n        \"\"\"\n        # Collect insertions\n        ins_elements = []\n        if elem.tagName == \"w:ins\":\n            ins_elements.append(elem)\n        else:\n            ins_elements.extend(elem.getElementsByTagName(\"w:ins\"))\n\n        # Validate that there are insertions to reject\n        if not ins_elements:\n            raise ValueError(\n                f\"revert_insertion requires w:ins elements. \"\n                f\"The provided element <{elem.tagName}> contains no insertions. \"\n            )\n\n        # Process all insertions - wrap all children in w:del\n        for ins_elem in ins_elements:\n            runs = list(ins_elem.getElementsByTagName(\"w:r\"))\n            if not runs:\n                continue\n\n            # Create deletion wrapper\n            del_wrapper = self.dom.createElement(\"w:del\")\n\n            # Process each run\n            for run in runs:\n                # Convert w:t → w:delText and w:rsidR → w:rsidDel\n                if run.hasAttribute(\"w:rsidR\"):\n                    run.setAttribute(\"w:rsidDel\", run.getAttribute(\"w:rsidR\"))\n                    run.removeAttribute(\"w:rsidR\")\n                elif not run.hasAttribute(\"w:rsidDel\"):\n                    run.setAttribute(\"w:rsidDel\", self.rsid)\n\n                for t_elem in list(run.getElementsByTagName(\"w:t\")):\n                    del_text = self.dom.createElement(\"w:delText\")\n                    # Copy ALL child nodes (not just firstChild) to handle entities\n                    while t_elem.firstChild:\n                        del_text.appendChild(t_elem.firstChild)\n                    for i in range(t_elem.attributes.length):\n                        attr = t_elem.attributes.item(i)\n                        del_text.setAttribute(attr.name, attr.value)\n                    t_elem.parentNode.replaceChild(del_text, t_elem)\n\n            # Move all children from ins to del wrapper\n            while ins_elem.firstChild:\n                del_wrapper.appendChild(ins_elem.firstChild)\n\n            # Add del wrapper back to ins\n            ins_elem.appendChild(del_wrapper)\n\n            # Inject attributes to the deletion wrapper\n            self._inject_attributes_to_nodes([del_wrapper])\n\n        return [elem]\n\n    def revert_deletion(self, elem):\n        \"\"\"Reject a deletion by re-inserting the deleted content.\n\n        Creates w:ins elements after each w:del, copying deleted content and\n        converting w:delText back to w:t.\n        Can process a single w:del element or a container element with multiple w:del.\n\n        Args:\n            elem: Element to process (w:del, w:p, w:body, etc.)\n\n        Returns:\n            list: If elem is w:del, returns [elem, new_ins]. Otherwise returns [elem].\n\n        Raises:\n            ValueError: If the element contains no w:del elements\n\n        Example:\n            # Reject a single deletion - returns [w:del, w:ins]\n            del_elem = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"3\"})\n            nodes = doc[\"word/document.xml\"].revert_deletion(del_elem)\n\n            # Reject all deletions in a paragraph - returns [para]\n            para = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=42)\n            nodes = doc[\"word/document.xml\"].revert_deletion(para)\n        \"\"\"\n        # Collect deletions FIRST - before we modify the DOM\n        del_elements = []\n        is_single_del = elem.tagName == \"w:del\"\n\n        if is_single_del:\n            del_elements.append(elem)\n        else:\n            del_elements.extend(elem.getElementsByTagName(\"w:del\"))\n\n        # Validate that there are deletions to reject\n        if not del_elements:\n            raise ValueError(\n                f\"revert_deletion requires w:del elements. \"\n                f\"The provided element <{elem.tagName}> contains no deletions. \"\n            )\n\n        # Track created insertion (only relevant if elem is a single w:del)\n        created_insertion = None\n\n        # Process all deletions - create insertions that copy the deleted content\n        for del_elem in del_elements:\n            # Clone the deleted runs and convert them to insertions\n            runs = list(del_elem.getElementsByTagName(\"w:r\"))\n            if not runs:\n                continue\n\n            # Create insertion wrapper\n            ins_elem = self.dom.createElement(\"w:ins\")\n\n            for run in runs:\n                # Clone the run\n                new_run = run.cloneNode(True)\n\n                # Convert w:delText → w:t\n                for del_text in list(new_run.getElementsByTagName(\"w:delText\")):\n                    t_elem = self.dom.createElement(\"w:t\")\n                    # Copy ALL child nodes (not just firstChild) to handle entities\n                    while del_text.firstChild:\n                        t_elem.appendChild(del_text.firstChild)\n                    for i in range(del_text.attributes.length):\n                        attr = del_text.attributes.item(i)\n                        t_elem.setAttribute(attr.name, attr.value)\n                    del_text.parentNode.replaceChild(t_elem, del_text)\n\n                # Update run attributes: w:rsidDel → w:rsidR\n                if new_run.hasAttribute(\"w:rsidDel\"):\n                    new_run.setAttribute(\"w:rsidR\", new_run.getAttribute(\"w:rsidDel\"))\n                    new_run.removeAttribute(\"w:rsidDel\")\n                elif not new_run.hasAttribute(\"w:rsidR\"):\n                    new_run.setAttribute(\"w:rsidR\", self.rsid)\n\n                ins_elem.appendChild(new_run)\n\n            # Insert the new insertion after the deletion\n            nodes = self.insert_after(del_elem, ins_elem.toxml())\n\n            # If processing a single w:del, track the created insertion\n            if is_single_del and nodes:\n                created_insertion = nodes[0]\n\n        # Return based on input type\n        if is_single_del and created_insertion:\n            return [elem, created_insertion]\n        else:\n            return [elem]\n\n    @staticmethod\n    def suggest_paragraph(xml_content: str) -> str:\n        \"\"\"Transform paragraph XML to add tracked change wrapping for insertion.\n\n        Wraps runs in <w:ins> and adds <w:ins/> to w:rPr in w:pPr for numbered lists.\n\n        Args:\n            xml_content: XML string containing a <w:p> element\n\n        Returns:\n            str: Transformed XML with tracked change wrapping\n        \"\"\"\n        wrapper = f'<root xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">{xml_content}</root>'\n        doc = minidom.parseString(wrapper)\n        para = doc.getElementsByTagName(\"w:p\")[0]\n\n        # Ensure w:pPr exists\n        pPr_list = para.getElementsByTagName(\"w:pPr\")\n        if not pPr_list:\n            pPr = doc.createElement(\"w:pPr\")\n            para.insertBefore(\n                pPr, para.firstChild\n            ) if para.firstChild else para.appendChild(pPr)\n        else:\n            pPr = pPr_list[0]\n\n        # Ensure w:rPr exists in w:pPr\n        rPr_list = pPr.getElementsByTagName(\"w:rPr\")\n        if not rPr_list:\n            rPr = doc.createElement(\"w:rPr\")\n            pPr.appendChild(rPr)\n        else:\n            rPr = rPr_list[0]\n\n        # Add <w:ins/> to w:rPr\n        ins_marker = doc.createElement(\"w:ins\")\n        rPr.insertBefore(\n            ins_marker, rPr.firstChild\n        ) if rPr.firstChild else rPr.appendChild(ins_marker)\n\n        # Wrap all non-pPr children in <w:ins>\n        ins_wrapper = doc.createElement(\"w:ins\")\n        for child in [c for c in para.childNodes if c.nodeName != \"w:pPr\"]:\n            para.removeChild(child)\n            ins_wrapper.appendChild(child)\n        para.appendChild(ins_wrapper)\n\n        return para.toxml()\n\n    def suggest_deletion(self, elem):\n        \"\"\"Mark a w:r or w:p element as deleted with tracked changes (in-place DOM manipulation).\n\n        For w:r: wraps in <w:del>, converts <w:t> to <w:delText>, preserves w:rPr\n        For w:p (regular): wraps content in <w:del>, converts <w:t> to <w:delText>\n        For w:p (numbered list): adds <w:del/> to w:rPr in w:pPr, wraps content in <w:del>\n\n        Args:\n            elem: A w:r or w:p DOM element without existing tracked changes\n\n        Returns:\n            Element: The modified element\n\n        Raises:\n            ValueError: If element has existing tracked changes or invalid structure\n        \"\"\"\n        if elem.nodeName == \"w:r\":\n            # Check for existing w:delText\n            if elem.getElementsByTagName(\"w:delText\"):\n                raise ValueError(\"w:r element already contains w:delText\")\n\n            # Convert w:t → w:delText\n            for t_elem in list(elem.getElementsByTagName(\"w:t\")):\n                del_text = self.dom.createElement(\"w:delText\")\n                # Copy ALL child nodes (not just firstChild) to handle entities\n                while t_elem.firstChild:\n                    del_text.appendChild(t_elem.firstChild)\n                # Preserve attributes like xml:space\n                for i in range(t_elem.attributes.length):\n                    attr = t_elem.attributes.item(i)\n                    del_text.setAttribute(attr.name, attr.value)\n                t_elem.parentNode.replaceChild(del_text, t_elem)\n\n            # Update run attributes: w:rsidR → w:rsidDel\n            if elem.hasAttribute(\"w:rsidR\"):\n                elem.setAttribute(\"w:rsidDel\", elem.getAttribute(\"w:rsidR\"))\n                elem.removeAttribute(\"w:rsidR\")\n            elif not elem.hasAttribute(\"w:rsidDel\"):\n                elem.setAttribute(\"w:rsidDel\", self.rsid)\n\n            # Wrap in w:del\n            del_wrapper = self.dom.createElement(\"w:del\")\n            parent = elem.parentNode\n            parent.insertBefore(del_wrapper, elem)\n            parent.removeChild(elem)\n            del_wrapper.appendChild(elem)\n\n            # Inject attributes to the deletion wrapper\n            self._inject_attributes_to_nodes([del_wrapper])\n\n            return del_wrapper\n\n        elif elem.nodeName == \"w:p\":\n            # Check for existing tracked changes\n            if elem.getElementsByTagName(\"w:ins\") or elem.getElementsByTagName(\"w:del\"):\n                raise ValueError(\"w:p element already contains tracked changes\")\n\n            # Check if it's a numbered list item\n            pPr_list = elem.getElementsByTagName(\"w:pPr\")\n            is_numbered = pPr_list and pPr_list[0].getElementsByTagName(\"w:numPr\")\n\n            if is_numbered:\n                # Add <w:del/> to w:rPr in w:pPr\n                pPr = pPr_list[0]\n                rPr_list = pPr.getElementsByTagName(\"w:rPr\")\n\n                if not rPr_list:\n                    rPr = self.dom.createElement(\"w:rPr\")\n                    pPr.appendChild(rPr)\n                else:\n                    rPr = rPr_list[0]\n\n                # Add <w:del/> marker\n                del_marker = self.dom.createElement(\"w:del\")\n                rPr.insertBefore(\n                    del_marker, rPr.firstChild\n                ) if rPr.firstChild else rPr.appendChild(del_marker)\n\n            # Convert w:t → w:delText in all runs\n            for t_elem in list(elem.getElementsByTagName(\"w:t\")):\n                del_text = self.dom.createElement(\"w:delText\")\n                # Copy ALL child nodes (not just firstChild) to handle entities\n                while t_elem.firstChild:\n                    del_text.appendChild(t_elem.firstChild)\n                # Preserve attributes like xml:space\n                for i in range(t_elem.attributes.length):\n                    attr = t_elem.attributes.item(i)\n                    del_text.setAttribute(attr.name, attr.value)\n                t_elem.parentNode.replaceChild(del_text, t_elem)\n\n            # Update run attributes: w:rsidR → w:rsidDel\n            for run in elem.getElementsByTagName(\"w:r\"):\n                if run.hasAttribute(\"w:rsidR\"):\n                    run.setAttribute(\"w:rsidDel\", run.getAttribute(\"w:rsidR\"))\n                    run.removeAttribute(\"w:rsidR\")\n                elif not run.hasAttribute(\"w:rsidDel\"):\n                    run.setAttribute(\"w:rsidDel\", self.rsid)\n\n            # Wrap all non-pPr children in <w:del>\n            del_wrapper = self.dom.createElement(\"w:del\")\n            for child in [c for c in elem.childNodes if c.nodeName != \"w:pPr\"]:\n                elem.removeChild(child)\n                del_wrapper.appendChild(child)\n            elem.appendChild(del_wrapper)\n\n            # Inject attributes to the deletion wrapper\n            self._inject_attributes_to_nodes([del_wrapper])\n\n            return elem\n\n        else:\n            raise ValueError(f\"Element must be w:r or w:p, got {elem.nodeName}\")\n\n\ndef _generate_hex_id() -> str:\n    \"\"\"Generate random 8-character hex ID for para/durable IDs.\n\n    Values are constrained to be less than 0x7FFFFFFF per OOXML spec:\n    - paraId must be < 0x80000000\n    - durableId must be < 0x7FFFFFFF\n    We use the stricter constraint (0x7FFFFFFF) for both.\n    \"\"\"\n    return f\"{random.randint(1, 0x7FFFFFFE):08X}\"\n\n\ndef _generate_rsid() -> str:\n    \"\"\"Generate random 8-character hex RSID.\"\"\"\n    return \"\".join(random.choices(\"0123456789ABCDEF\", k=8))\n\n\nclass Document:\n    \"\"\"Manages comments in unpacked Word documents.\"\"\"\n\n    def __init__(\n        self,\n        unpacked_dir,\n        rsid=None,\n        track_revisions=False,\n        author=\"Claude\",\n        initials=\"C\",\n    ):\n        \"\"\"\n        Initialize with path to unpacked Word document directory.\n        Automatically sets up comment infrastructure (people.xml, RSIDs).\n\n        Args:\n            unpacked_dir: Path to unpacked DOCX directory (must contain word/ subdirectory)\n            rsid: Optional RSID to use for all comment elements. If not provided, one will be generated.\n            track_revisions: If True, enables track revisions in settings.xml (default: False)\n            author: Default author name for comments (default: \"Claude\")\n            initials: Default author initials for comments (default: \"C\")\n        \"\"\"\n        self.original_path = Path(unpacked_dir)\n\n        if not self.original_path.exists() or not self.original_path.is_dir():\n            raise ValueError(f\"Directory not found: {unpacked_dir}\")\n\n        # Create temporary directory with subdirectories for unpacked content and baseline\n        self.temp_dir = tempfile.mkdtemp(prefix=\"docx_\")\n        self.unpacked_path = Path(self.temp_dir) / \"unpacked\"\n        shutil.copytree(self.original_path, self.unpacked_path)\n\n        # Pack original directory into temporary .docx for validation baseline (outside unpacked dir)\n        self.original_docx = Path(self.temp_dir) / \"original.docx\"\n        pack_document(self.original_path, self.original_docx, validate=False)\n\n        self.word_path = self.unpacked_path / \"word\"\n\n        # Generate RSID if not provided\n        self.rsid = rsid if rsid else _generate_rsid()\n        print(f\"Using RSID: {self.rsid}\")\n\n        # Set default author and initials\n        self.author = author\n        self.initials = initials\n\n        # Cache for lazy-loaded editors\n        self._editors = {}\n\n        # Comment file paths\n        self.comments_path = self.word_path / \"comments.xml\"\n        self.comments_extended_path = self.word_path / \"commentsExtended.xml\"\n        self.comments_ids_path = self.word_path / \"commentsIds.xml\"\n        self.comments_extensible_path = self.word_path / \"commentsExtensible.xml\"\n\n        # Load existing comments and determine next ID (before setup modifies files)\n        self.existing_comments = self._load_existing_comments()\n        self.next_comment_id = self._get_next_comment_id()\n\n        # Convenient access to document.xml editor (semi-private)\n        self._document = self[\"word/document.xml\"]\n\n        # Setup tracked changes infrastructure\n        self._setup_tracking(track_revisions=track_revisions)\n\n        # Add author to people.xml\n        self._add_author_to_people(author)\n\n    def __getitem__(self, xml_path: str) -> DocxXMLEditor:\n        \"\"\"\n        Get or create a DocxXMLEditor for the specified XML file.\n\n        Enables lazy-loaded editors with bracket notation:\n            node = doc[\"word/document.xml\"].get_node(tag=\"w:p\", line_number=42)\n\n        Args:\n            xml_path: Relative path to XML file (e.g., \"word/document.xml\", \"word/comments.xml\")\n\n        Returns:\n            DocxXMLEditor instance for the specified file\n\n        Raises:\n            ValueError: If the file does not exist\n\n        Example:\n            # Get node from document.xml\n            node = doc[\"word/document.xml\"].get_node(tag=\"w:del\", attrs={\"w:id\": \"1\"})\n\n            # Get node from comments.xml\n            comment = doc[\"word/comments.xml\"].get_node(tag=\"w:comment\", attrs={\"w:id\": \"0\"})\n        \"\"\"\n        if xml_path not in self._editors:\n            file_path = self.unpacked_path / xml_path\n            if not file_path.exists():\n                raise ValueError(f\"XML file not found: {xml_path}\")\n            # Use DocxXMLEditor with RSID, author, and initials for all editors\n            self._editors[xml_path] = DocxXMLEditor(\n                file_path, rsid=self.rsid, author=self.author, initials=self.initials\n            )\n        return self._editors[xml_path]\n\n    def add_comment(self, start, end, text: str) -> int:\n        \"\"\"\n        Add a comment spanning from one element to another.\n\n        Args:\n            start: DOM element for the starting point\n            end: DOM element for the ending point\n            text: Comment content\n\n        Returns:\n            The comment ID that was created\n\n        Example:\n            start_node = cm.get_document_node(tag=\"w:del\", id=\"1\")\n            end_node = cm.get_document_node(tag=\"w:ins\", id=\"2\")\n            cm.add_comment(start=start_node, end=end_node, text=\"Explanation\")\n        \"\"\"\n        comment_id = self.next_comment_id\n        para_id = _generate_hex_id()\n        durable_id = _generate_hex_id()\n        timestamp = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n\n        # Add comment ranges to document.xml immediately\n        self._document.insert_before(start, self._comment_range_start_xml(comment_id))\n\n        # If end node is a paragraph, append comment markup inside it\n        # Otherwise insert after it (for run-level anchors)\n        if end.tagName == \"w:p\":\n            self._document.append_to(end, self._comment_range_end_xml(comment_id))\n        else:\n            self._document.insert_after(end, self._comment_range_end_xml(comment_id))\n\n        # Add to comments.xml immediately\n        self._add_to_comments_xml(\n            comment_id, para_id, text, self.author, self.initials, timestamp\n        )\n\n        # Add to commentsExtended.xml immediately\n        self._add_to_comments_extended_xml(para_id, parent_para_id=None)\n\n        # Add to commentsIds.xml immediately\n        self._add_to_comments_ids_xml(para_id, durable_id)\n\n        # Add to commentsExtensible.xml immediately\n        self._add_to_comments_extensible_xml(durable_id)\n\n        # Update existing_comments so replies work\n        self.existing_comments[comment_id] = {\"para_id\": para_id}\n\n        self.next_comment_id += 1\n        return comment_id\n\n    def reply_to_comment(\n        self,\n        parent_comment_id: int,\n        text: str,\n    ) -> int:\n        \"\"\"\n        Add a reply to an existing comment.\n\n        Args:\n            parent_comment_id: The w:id of the parent comment to reply to\n            text: Reply text\n\n        Returns:\n            The comment ID that was created for the reply\n\n        Example:\n            cm.reply_to_comment(parent_comment_id=0, text=\"I agree with this change\")\n        \"\"\"\n        if parent_comment_id not in self.existing_comments:\n            raise ValueError(f\"Parent comment with id={parent_comment_id} not found\")\n\n        parent_info = self.existing_comments[parent_comment_id]\n        comment_id = self.next_comment_id\n        para_id = _generate_hex_id()\n        durable_id = _generate_hex_id()\n        timestamp = datetime.now(timezone.utc).strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n\n        # Add comment ranges to document.xml immediately\n        parent_start_elem = self._document.get_node(\n            tag=\"w:commentRangeStart\", attrs={\"w:id\": str(parent_comment_id)}\n        )\n        parent_ref_elem = self._document.get_node(\n            tag=\"w:commentReference\", attrs={\"w:id\": str(parent_comment_id)}\n        )\n\n        self._document.insert_after(\n            parent_start_elem, self._comment_range_start_xml(comment_id)\n        )\n        parent_ref_run = parent_ref_elem.parentNode\n        self._document.insert_after(\n            parent_ref_run, f'<w:commentRangeEnd w:id=\"{comment_id}\"/>'\n        )\n        self._document.insert_after(\n            parent_ref_run, self._comment_ref_run_xml(comment_id)\n        )\n\n        # Add to comments.xml immediately\n        self._add_to_comments_xml(\n            comment_id, para_id, text, self.author, self.initials, timestamp\n        )\n\n        # Add to commentsExtended.xml immediately (with parent)\n        self._add_to_comments_extended_xml(\n            para_id, parent_para_id=parent_info[\"para_id\"]\n        )\n\n        # Add to commentsIds.xml immediately\n        self._add_to_comments_ids_xml(para_id, durable_id)\n\n        # Add to commentsExtensible.xml immediately\n        self._add_to_comments_extensible_xml(durable_id)\n\n        # Update existing_comments so replies work\n        self.existing_comments[comment_id] = {\"para_id\": para_id}\n\n        self.next_comment_id += 1\n        return comment_id\n\n    def __del__(self):\n        \"\"\"Clean up temporary directory on deletion.\"\"\"\n        if hasattr(self, \"temp_dir\") and Path(self.temp_dir).exists():\n            shutil.rmtree(self.temp_dir)\n\n    def validate(self) -> None:\n        \"\"\"\n        Validate the document against XSD schema and redlining rules.\n\n        Raises:\n            ValueError: If validation fails.\n        \"\"\"\n        # Create validators with current state\n        schema_validator = DOCXSchemaValidator(\n            self.unpacked_path, self.original_docx, verbose=False\n        )\n        redlining_validator = RedliningValidator(\n            self.unpacked_path, self.original_docx, verbose=False\n        )\n\n        # Run validations\n        if not schema_validator.validate():\n            raise ValueError(\"Schema validation failed\")\n        if not redlining_validator.validate():\n            raise ValueError(\"Redlining validation failed\")\n\n    def save(self, destination=None, validate=True) -> None:\n        \"\"\"\n        Save all modified XML files to disk and copy to destination directory.\n\n        This persists all changes made via add_comment() and reply_to_comment().\n\n        Args:\n            destination: Optional path to save to. If None, saves back to original directory.\n            validate: If True, validates document before saving (default: True).\n        \"\"\"\n        # Only ensure comment relationships and content types if comment files exist\n        if self.comments_path.exists():\n            self._ensure_comment_relationships()\n            self._ensure_comment_content_types()\n\n        # Save all modified XML files in temp directory\n        for editor in self._editors.values():\n            editor.save()\n\n        # Validate by default\n        if validate:\n            self.validate()\n\n        # Copy contents from temp directory to destination (or original directory)\n        target_path = Path(destination) if destination else self.original_path\n        shutil.copytree(self.unpacked_path, target_path, dirs_exist_ok=True)\n\n    # ==================== Private: Initialization ====================\n\n    def _get_next_comment_id(self):\n        \"\"\"Get the next available comment ID.\"\"\"\n        if not self.comments_path.exists():\n            return 0\n\n        editor = self[\"word/comments.xml\"]\n        max_id = -1\n        for comment_elem in editor.dom.getElementsByTagName(\"w:comment\"):\n            comment_id = comment_elem.getAttribute(\"w:id\")\n            if comment_id:\n                try:\n                    max_id = max(max_id, int(comment_id))\n                except ValueError:\n                    pass\n        return max_id + 1\n\n    def _load_existing_comments(self):\n        \"\"\"Load existing comments from files to enable replies.\"\"\"\n        if not self.comments_path.exists():\n            return {}\n\n        editor = self[\"word/comments.xml\"]\n        existing = {}\n\n        for comment_elem in editor.dom.getElementsByTagName(\"w:comment\"):\n            comment_id = comment_elem.getAttribute(\"w:id\")\n            if not comment_id:\n                continue\n\n            # Find para_id from the w:p element within the comment\n            para_id = None\n            for p_elem in comment_elem.getElementsByTagName(\"w:p\"):\n                para_id = p_elem.getAttribute(\"w14:paraId\")\n                if para_id:\n                    break\n\n            if not para_id:\n                continue\n\n            existing[int(comment_id)] = {\"para_id\": para_id}\n\n        return existing\n\n    # ==================== Private: Setup Methods ====================\n\n    def _setup_tracking(self, track_revisions=False):\n        \"\"\"Set up comment infrastructure in unpacked directory.\n\n        Args:\n            track_revisions: If True, enables track revisions in settings.xml\n        \"\"\"\n        # Create or update word/people.xml\n        people_file = self.word_path / \"people.xml\"\n        self._update_people_xml(people_file)\n\n        # Update XML files\n        self._add_content_type_for_people(self.unpacked_path / \"[Content_Types].xml\")\n        self._add_relationship_for_people(\n            self.word_path / \"_rels\" / \"document.xml.rels\"\n        )\n\n        # Always add RSID to settings.xml, optionally enable trackRevisions\n        self._update_settings(\n            self.word_path / \"settings.xml\", track_revisions=track_revisions\n        )\n\n    def _update_people_xml(self, path):\n        \"\"\"Create people.xml if it doesn't exist.\"\"\"\n        if not path.exists():\n            # Copy from template\n            shutil.copy(TEMPLATE_DIR / \"people.xml\", path)\n\n    def _add_content_type_for_people(self, path):\n        \"\"\"Add people.xml content type to [Content_Types].xml if not already present.\"\"\"\n        editor = self[\"[Content_Types].xml\"]\n\n        if self._has_override(editor, \"/word/people.xml\"):\n            return\n\n        # Add Override element\n        root = editor.dom.documentElement\n        override_xml = '<Override PartName=\"/word/people.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml\"/>'\n        editor.append_to(root, override_xml)\n\n    def _add_relationship_for_people(self, path):\n        \"\"\"Add people.xml relationship to document.xml.rels if not already present.\"\"\"\n        editor = self[\"word/_rels/document.xml.rels\"]\n\n        if self._has_relationship(editor, \"people.xml\"):\n            return\n\n        root = editor.dom.documentElement\n        root_tag = root.tagName  # type: ignore\n        prefix = root_tag.split(\":\")[0] + \":\" if \":\" in root_tag else \"\"\n        next_rid = editor.get_next_rid()\n\n        # Create the relationship entry\n        rel_xml = f'<{prefix}Relationship Id=\"{next_rid}\" Type=\"http://schemas.microsoft.com/office/2011/relationships/people\" Target=\"people.xml\"/>'\n        editor.append_to(root, rel_xml)\n\n    def _update_settings(self, path, track_revisions=False):\n        \"\"\"Add RSID and optionally enable track revisions in settings.xml.\n\n        Args:\n            path: Path to settings.xml\n            track_revisions: If True, adds trackRevisions element\n\n        Places elements per OOXML schema order:\n        - trackRevisions: early (before defaultTabStop)\n        - rsids: late (after compat)\n        \"\"\"\n        editor = self[\"word/settings.xml\"]\n        root = editor.get_node(tag=\"w:settings\")\n        prefix = root.tagName.split(\":\")[0] if \":\" in root.tagName else \"w\"\n\n        # Conditionally add trackRevisions if requested\n        if track_revisions:\n            track_revisions_exists = any(\n                elem.tagName == f\"{prefix}:trackRevisions\"\n                for elem in editor.dom.getElementsByTagName(f\"{prefix}:trackRevisions\")\n            )\n\n            if not track_revisions_exists:\n                track_rev_xml = f\"<{prefix}:trackRevisions/>\"\n                # Try to insert before documentProtection, defaultTabStop, or at start\n                inserted = False\n                for tag in [f\"{prefix}:documentProtection\", f\"{prefix}:defaultTabStop\"]:\n                    elements = editor.dom.getElementsByTagName(tag)\n                    if elements:\n                        editor.insert_before(elements[0], track_rev_xml)\n                        inserted = True\n                        break\n                if not inserted:\n                    # Insert as first child of settings\n                    if root.firstChild:\n                        editor.insert_before(root.firstChild, track_rev_xml)\n                    else:\n                        editor.append_to(root, track_rev_xml)\n\n        # Always check if rsids section exists\n        rsids_elements = editor.dom.getElementsByTagName(f\"{prefix}:rsids\")\n\n        if not rsids_elements:\n            # Add new rsids section\n            rsids_xml = f'''<{prefix}:rsids>\n  <{prefix}:rsidRoot {prefix}:val=\"{self.rsid}\"/>\n  <{prefix}:rsid {prefix}:val=\"{self.rsid}\"/>\n</{prefix}:rsids>'''\n\n            # Try to insert after compat, before clrSchemeMapping, or before closing tag\n            inserted = False\n            compat_elements = editor.dom.getElementsByTagName(f\"{prefix}:compat\")\n            if compat_elements:\n                editor.insert_after(compat_elements[0], rsids_xml)\n                inserted = True\n\n            if not inserted:\n                clr_elements = editor.dom.getElementsByTagName(\n                    f\"{prefix}:clrSchemeMapping\"\n                )\n                if clr_elements:\n                    editor.insert_before(clr_elements[0], rsids_xml)\n                    inserted = True\n\n            if not inserted:\n                editor.append_to(root, rsids_xml)\n        else:\n            # Check if this rsid already exists\n            rsids_elem = rsids_elements[0]\n            rsid_exists = any(\n                elem.getAttribute(f\"{prefix}:val\") == self.rsid\n                for elem in rsids_elem.getElementsByTagName(f\"{prefix}:rsid\")\n            )\n\n            if not rsid_exists:\n                rsid_xml = f'<{prefix}:rsid {prefix}:val=\"{self.rsid}\"/>'\n                editor.append_to(rsids_elem, rsid_xml)\n\n    # ==================== Private: XML File Creation ====================\n\n    def _add_to_comments_xml(\n        self, comment_id, para_id, text, author, initials, timestamp\n    ):\n        \"\"\"Add a single comment to comments.xml.\"\"\"\n        if not self.comments_path.exists():\n            shutil.copy(TEMPLATE_DIR / \"comments.xml\", self.comments_path)\n\n        editor = self[\"word/comments.xml\"]\n        root = editor.get_node(tag=\"w:comments\")\n\n        escaped_text = (\n            text.replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\")\n        )\n        # Note: w:rsidR, w:rsidRDefault, w:rsidP on w:p, w:rsidR on w:r,\n        # and w:author, w:date, w:initials on w:comment are automatically added by DocxXMLEditor\n        comment_xml = f'''<w:comment w:id=\"{comment_id}\">\n  <w:p w14:paraId=\"{para_id}\" w14:textId=\"77777777\">\n    <w:r><w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr><w:annotationRef/></w:r>\n    <w:r><w:rPr><w:color w:val=\"000000\"/><w:sz w:val=\"20\"/><w:szCs w:val=\"20\"/></w:rPr><w:t>{escaped_text}</w:t></w:r>\n  </w:p>\n</w:comment>'''\n        editor.append_to(root, comment_xml)\n\n    def _add_to_comments_extended_xml(self, para_id, parent_para_id):\n        \"\"\"Add a single comment to commentsExtended.xml.\"\"\"\n        if not self.comments_extended_path.exists():\n            shutil.copy(\n                TEMPLATE_DIR / \"commentsExtended.xml\", self.comments_extended_path\n            )\n\n        editor = self[\"word/commentsExtended.xml\"]\n        root = editor.get_node(tag=\"w15:commentsEx\")\n\n        if parent_para_id:\n            xml = f'<w15:commentEx w15:paraId=\"{para_id}\" w15:paraIdParent=\"{parent_para_id}\" w15:done=\"0\"/>'\n        else:\n            xml = f'<w15:commentEx w15:paraId=\"{para_id}\" w15:done=\"0\"/>'\n        editor.append_to(root, xml)\n\n    def _add_to_comments_ids_xml(self, para_id, durable_id):\n        \"\"\"Add a single comment to commentsIds.xml.\"\"\"\n        if not self.comments_ids_path.exists():\n            shutil.copy(TEMPLATE_DIR / \"commentsIds.xml\", self.comments_ids_path)\n\n        editor = self[\"word/commentsIds.xml\"]\n        root = editor.get_node(tag=\"w16cid:commentsIds\")\n\n        xml = f'<w16cid:commentId w16cid:paraId=\"{para_id}\" w16cid:durableId=\"{durable_id}\"/>'\n        editor.append_to(root, xml)\n\n    def _add_to_comments_extensible_xml(self, durable_id):\n        \"\"\"Add a single comment to commentsExtensible.xml.\"\"\"\n        if not self.comments_extensible_path.exists():\n            shutil.copy(\n                TEMPLATE_DIR / \"commentsExtensible.xml\", self.comments_extensible_path\n            )\n\n        editor = self[\"word/commentsExtensible.xml\"]\n        root = editor.get_node(tag=\"w16cex:commentsExtensible\")\n\n        xml = f'<w16cex:commentExtensible w16cex:durableId=\"{durable_id}\"/>'\n        editor.append_to(root, xml)\n\n    # ==================== Private: XML Fragments ====================\n\n    def _comment_range_start_xml(self, comment_id):\n        \"\"\"Generate XML for comment range start.\"\"\"\n        return f'<w:commentRangeStart w:id=\"{comment_id}\"/>'\n\n    def _comment_range_end_xml(self, comment_id):\n        \"\"\"Generate XML for comment range end with reference run.\n\n        Note: w:rsidR is automatically added by DocxXMLEditor.\n        \"\"\"\n        return f'''<w:commentRangeEnd w:id=\"{comment_id}\"/>\n<w:r>\n  <w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr>\n  <w:commentReference w:id=\"{comment_id}\"/>\n</w:r>'''\n\n    def _comment_ref_run_xml(self, comment_id):\n        \"\"\"Generate XML for comment reference run.\n\n        Note: w:rsidR is automatically added by DocxXMLEditor.\n        \"\"\"\n        return f'''<w:r>\n  <w:rPr><w:rStyle w:val=\"CommentReference\"/></w:rPr>\n  <w:commentReference w:id=\"{comment_id}\"/>\n</w:r>'''\n\n    # ==================== Private: Metadata Updates ====================\n\n    def _has_relationship(self, editor, target):\n        \"\"\"Check if a relationship with given target exists.\"\"\"\n        for rel_elem in editor.dom.getElementsByTagName(\"Relationship\"):\n            if rel_elem.getAttribute(\"Target\") == target:\n                return True\n        return False\n\n    def _has_override(self, editor, part_name):\n        \"\"\"Check if an override with given part name exists.\"\"\"\n        for override_elem in editor.dom.getElementsByTagName(\"Override\"):\n            if override_elem.getAttribute(\"PartName\") == part_name:\n                return True\n        return False\n\n    def _has_author(self, editor, author):\n        \"\"\"Check if an author already exists in people.xml.\"\"\"\n        for person_elem in editor.dom.getElementsByTagName(\"w15:person\"):\n            if person_elem.getAttribute(\"w15:author\") == author:\n                return True\n        return False\n\n    def _add_author_to_people(self, author):\n        \"\"\"Add author to people.xml (called during initialization).\"\"\"\n        people_path = self.word_path / \"people.xml\"\n\n        # people.xml should already exist from _setup_tracking\n        if not people_path.exists():\n            raise ValueError(\"people.xml should exist after _setup_tracking\")\n\n        editor = self[\"word/people.xml\"]\n        root = editor.get_node(tag=\"w15:people\")\n\n        # Check if author already exists\n        if self._has_author(editor, author):\n            return\n\n        # Add author with proper XML escaping to prevent injection\n        escaped_author = html.escape(author, quote=True)\n        person_xml = f'''<w15:person w15:author=\"{escaped_author}\">\n  <w15:presenceInfo w15:providerId=\"None\" w15:userId=\"{escaped_author}\"/>\n</w15:person>'''\n        editor.append_to(root, person_xml)\n\n    def _ensure_comment_relationships(self):\n        \"\"\"Ensure word/_rels/document.xml.rels has comment relationships.\"\"\"\n        editor = self[\"word/_rels/document.xml.rels\"]\n\n        if self._has_relationship(editor, \"comments.xml\"):\n            return\n\n        root = editor.dom.documentElement\n        root_tag = root.tagName  # type: ignore\n        prefix = root_tag.split(\":\")[0] + \":\" if \":\" in root_tag else \"\"\n        next_rid_num = int(editor.get_next_rid()[3:])\n\n        # Add relationship elements\n        rels = [\n            (\n                next_rid_num,\n                \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\",\n                \"comments.xml\",\n            ),\n            (\n                next_rid_num + 1,\n                \"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\",\n                \"commentsExtended.xml\",\n            ),\n            (\n                next_rid_num + 2,\n                \"http://schemas.microsoft.com/office/2016/09/relationships/commentsIds\",\n                \"commentsIds.xml\",\n            ),\n            (\n                next_rid_num + 3,\n                \"http://schemas.microsoft.com/office/2018/08/relationships/commentsExtensible\",\n                \"commentsExtensible.xml\",\n            ),\n        ]\n\n        for rel_id, rel_type, target in rels:\n            rel_xml = f'<{prefix}Relationship Id=\"rId{rel_id}\" Type=\"{rel_type}\" Target=\"{target}\"/>'\n            editor.append_to(root, rel_xml)\n\n    def _ensure_comment_content_types(self):\n        \"\"\"Ensure [Content_Types].xml has comment content types.\"\"\"\n        editor = self[\"[Content_Types].xml\"]\n\n        if self._has_override(editor, \"/word/comments.xml\"):\n            return\n\n        root = editor.dom.documentElement\n\n        # Add Override elements\n        overrides = [\n            (\n                \"/word/comments.xml\",\n                \"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml\",\n            ),\n            (\n                \"/word/commentsExtended.xml\",\n                \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml\",\n            ),\n            (\n                \"/word/commentsIds.xml\",\n                \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml\",\n            ),\n            (\n                \"/word/commentsExtensible.xml\",\n                \"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml\",\n            ),\n        ]\n\n        for part_name, content_type in overrides:\n            override_xml = (\n                f'<Override PartName=\"{part_name}\" ContentType=\"{content_type}\"/>'\n            )\n            editor.append_to(root, override_xml)\n"
  },
  {
    "path": "document-skills/docx/scripts/templates/comments.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w:comments xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w:comments>"
  },
  {
    "path": "document-skills/docx/scripts/templates/commentsExtended.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w15:commentsEx xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w15:commentsEx>"
  },
  {
    "path": "document-skills/docx/scripts/templates/commentsExtensible.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w16cex:commentsExtensible xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" xmlns:cr=\"http://schemas.microsoft.com/office/comments/2020/reactions\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl cr w16du wp14\">\n</w16cex:commentsExtensible>"
  },
  {
    "path": "document-skills/docx/scripts/templates/commentsIds.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w16cid:commentsIds xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:oel=\"http://schemas.microsoft.com/office/2019/extlst\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16du=\"http://schemas.microsoft.com/office/word/2023/wordml/word16du\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16sdtfl=\"http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14\">\n</w16cid:commentsIds>"
  },
  {
    "path": "document-skills/docx/scripts/templates/people.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<w15:people xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n</w15:people>"
  },
  {
    "path": "document-skills/docx/scripts/utilities.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nUtilities for editing OOXML documents.\n\nThis module provides XMLEditor, a tool for manipulating XML files with support for\nline-number-based node finding and DOM manipulation. Each element is automatically\nannotated with its original line and column position during parsing.\n\nExample usage:\n    editor = XMLEditor(\"document.xml\")\n\n    # Find node by line number or range\n    elem = editor.get_node(tag=\"w:r\", line_number=519)\n    elem = editor.get_node(tag=\"w:p\", line_number=range(100, 200))\n\n    # Find node by text content\n    elem = editor.get_node(tag=\"w:p\", contains=\"specific text\")\n\n    # Find node by attributes\n    elem = editor.get_node(tag=\"w:r\", attrs={\"w:id\": \"target\"})\n\n    # Combine filters\n    elem = editor.get_node(tag=\"w:p\", line_number=range(1, 50), contains=\"text\")\n\n    # Replace, insert, or manipulate\n    new_elem = editor.replace_node(elem, \"<w:r><w:t>new text</w:t></w:r>\")\n    editor.insert_after(new_elem, \"<w:r><w:t>more</w:t></w:r>\")\n\n    # Save changes\n    editor.save()\n\"\"\"\n\nimport html\nfrom pathlib import Path\nfrom typing import Optional, Union\n\nimport defusedxml.minidom\nimport defusedxml.sax\n\n\nclass XMLEditor:\n    \"\"\"\n    Editor for manipulating OOXML XML files with line-number-based node finding.\n\n    This class parses XML files and tracks the original line and column position\n    of each element. This enables finding nodes by their line number in the original\n    file, which is useful when working with Read tool output.\n\n    Attributes:\n        xml_path: Path to the XML file being edited\n        encoding: Detected encoding of the XML file ('ascii' or 'utf-8')\n        dom: Parsed DOM tree with parse_position attributes on elements\n    \"\"\"\n\n    def __init__(self, xml_path):\n        \"\"\"\n        Initialize with path to XML file and parse with line number tracking.\n\n        Args:\n            xml_path: Path to XML file to edit (str or Path)\n\n        Raises:\n            ValueError: If the XML file does not exist\n        \"\"\"\n        self.xml_path = Path(xml_path)\n        if not self.xml_path.exists():\n            raise ValueError(f\"XML file not found: {xml_path}\")\n\n        with open(self.xml_path, \"rb\") as f:\n            header = f.read(200).decode(\"utf-8\", errors=\"ignore\")\n        self.encoding = \"ascii\" if 'encoding=\"ascii\"' in header else \"utf-8\"\n\n        parser = _create_line_tracking_parser()\n        self.dom = defusedxml.minidom.parse(str(self.xml_path), parser)\n\n    def get_node(\n        self,\n        tag: str,\n        attrs: Optional[dict[str, str]] = None,\n        line_number: Optional[Union[int, range]] = None,\n        contains: Optional[str] = None,\n    ):\n        \"\"\"\n        Get a DOM element by tag and identifier.\n\n        Finds an element by either its line number in the original file or by\n        matching attribute values. Exactly one match must be found.\n\n        Args:\n            tag: The XML tag name (e.g., \"w:del\", \"w:ins\", \"w:r\")\n            attrs: Dictionary of attribute name-value pairs to match (e.g., {\"w:id\": \"1\"})\n            line_number: Line number (int) or line range (range) in original XML file (1-indexed)\n            contains: Text string that must appear in any text node within the element.\n                      Supports both entity notation (&#8220;) and Unicode characters (\\u201c).\n\n        Returns:\n            defusedxml.minidom.Element: The matching DOM element\n\n        Raises:\n            ValueError: If node not found or multiple matches found\n\n        Example:\n            elem = editor.get_node(tag=\"w:r\", line_number=519)\n            elem = editor.get_node(tag=\"w:r\", line_number=range(100, 200))\n            elem = editor.get_node(tag=\"w:del\", attrs={\"w:id\": \"1\"})\n            elem = editor.get_node(tag=\"w:p\", attrs={\"w14:paraId\": \"12345678\"})\n            elem = editor.get_node(tag=\"w:commentRangeStart\", attrs={\"w:id\": \"0\"})\n            elem = editor.get_node(tag=\"w:p\", contains=\"specific text\")\n            elem = editor.get_node(tag=\"w:t\", contains=\"&#8220;Agreement\")  # Entity notation\n            elem = editor.get_node(tag=\"w:t\", contains=\"\\u201cAgreement\")   # Unicode character\n        \"\"\"\n        matches = []\n        for elem in self.dom.getElementsByTagName(tag):\n            # Check line_number filter\n            if line_number is not None:\n                parse_pos = getattr(elem, \"parse_position\", (None,))\n                elem_line = parse_pos[0]\n\n                # Handle both single line number and range\n                if isinstance(line_number, range):\n                    if elem_line not in line_number:\n                        continue\n                else:\n                    if elem_line != line_number:\n                        continue\n\n            # Check attrs filter\n            if attrs is not None:\n                if not all(\n                    elem.getAttribute(attr_name) == attr_value\n                    for attr_name, attr_value in attrs.items()\n                ):\n                    continue\n\n            # Check contains filter\n            if contains is not None:\n                elem_text = self._get_element_text(elem)\n                # Normalize the search string: convert HTML entities to Unicode characters\n                # This allows searching for both \"&#8220;Rowan\" and \"\"Rowan\"\n                normalized_contains = html.unescape(contains)\n                if normalized_contains not in elem_text:\n                    continue\n\n            # If all applicable filters passed, this is a match\n            matches.append(elem)\n\n        if not matches:\n            # Build descriptive error message\n            filters = []\n            if line_number is not None:\n                line_str = (\n                    f\"lines {line_number.start}-{line_number.stop - 1}\"\n                    if isinstance(line_number, range)\n                    else f\"line {line_number}\"\n                )\n                filters.append(f\"at {line_str}\")\n            if attrs is not None:\n                filters.append(f\"with attributes {attrs}\")\n            if contains is not None:\n                filters.append(f\"containing '{contains}'\")\n\n            filter_desc = \" \".join(filters) if filters else \"\"\n            base_msg = f\"Node not found: <{tag}> {filter_desc}\".strip()\n\n            # Add helpful hint based on filters used\n            if contains:\n                hint = \"Text may be split across elements or use different wording.\"\n            elif line_number:\n                hint = \"Line numbers may have changed if document was modified.\"\n            elif attrs:\n                hint = \"Verify attribute values are correct.\"\n            else:\n                hint = \"Try adding filters (attrs, line_number, or contains).\"\n\n            raise ValueError(f\"{base_msg}. {hint}\")\n        if len(matches) > 1:\n            raise ValueError(\n                f\"Multiple nodes found: <{tag}>. \"\n                f\"Add more filters (attrs, line_number, or contains) to narrow the search.\"\n            )\n        return matches[0]\n\n    def _get_element_text(self, elem):\n        \"\"\"\n        Recursively extract all text content from an element.\n\n        Skips text nodes that contain only whitespace (spaces, tabs, newlines),\n        which typically represent XML formatting rather than document content.\n\n        Args:\n            elem: defusedxml.minidom.Element to extract text from\n\n        Returns:\n            str: Concatenated text from all non-whitespace text nodes within the element\n        \"\"\"\n        text_parts = []\n        for node in elem.childNodes:\n            if node.nodeType == node.TEXT_NODE:\n                # Skip whitespace-only text nodes (XML formatting)\n                if node.data.strip():\n                    text_parts.append(node.data)\n            elif node.nodeType == node.ELEMENT_NODE:\n                text_parts.append(self._get_element_text(node))\n        return \"\".join(text_parts)\n\n    def replace_node(self, elem, new_content):\n        \"\"\"\n        Replace a DOM element with new XML content.\n\n        Args:\n            elem: defusedxml.minidom.Element to replace\n            new_content: String containing XML to replace the node with\n\n        Returns:\n            List[defusedxml.minidom.Node]: All inserted nodes\n\n        Example:\n            new_nodes = editor.replace_node(old_elem, \"<w:r><w:t>text</w:t></w:r>\")\n        \"\"\"\n        parent = elem.parentNode\n        nodes = self._parse_fragment(new_content)\n        for node in nodes:\n            parent.insertBefore(node, elem)\n        parent.removeChild(elem)\n        return nodes\n\n    def insert_after(self, elem, xml_content):\n        \"\"\"\n        Insert XML content after a DOM element.\n\n        Args:\n            elem: defusedxml.minidom.Element to insert after\n            xml_content: String containing XML to insert\n\n        Returns:\n            List[defusedxml.minidom.Node]: All inserted nodes\n\n        Example:\n            new_nodes = editor.insert_after(elem, \"<w:r><w:t>text</w:t></w:r>\")\n        \"\"\"\n        parent = elem.parentNode\n        next_sibling = elem.nextSibling\n        nodes = self._parse_fragment(xml_content)\n        for node in nodes:\n            if next_sibling:\n                parent.insertBefore(node, next_sibling)\n            else:\n                parent.appendChild(node)\n        return nodes\n\n    def insert_before(self, elem, xml_content):\n        \"\"\"\n        Insert XML content before a DOM element.\n\n        Args:\n            elem: defusedxml.minidom.Element to insert before\n            xml_content: String containing XML to insert\n\n        Returns:\n            List[defusedxml.minidom.Node]: All inserted nodes\n\n        Example:\n            new_nodes = editor.insert_before(elem, \"<w:r><w:t>text</w:t></w:r>\")\n        \"\"\"\n        parent = elem.parentNode\n        nodes = self._parse_fragment(xml_content)\n        for node in nodes:\n            parent.insertBefore(node, elem)\n        return nodes\n\n    def append_to(self, elem, xml_content):\n        \"\"\"\n        Append XML content as a child of a DOM element.\n\n        Args:\n            elem: defusedxml.minidom.Element to append to\n            xml_content: String containing XML to append\n\n        Returns:\n            List[defusedxml.minidom.Node]: All inserted nodes\n\n        Example:\n            new_nodes = editor.append_to(elem, \"<w:r><w:t>text</w:t></w:r>\")\n        \"\"\"\n        nodes = self._parse_fragment(xml_content)\n        for node in nodes:\n            elem.appendChild(node)\n        return nodes\n\n    def get_next_rid(self):\n        \"\"\"Get the next available rId for relationships files.\"\"\"\n        max_id = 0\n        for rel_elem in self.dom.getElementsByTagName(\"Relationship\"):\n            rel_id = rel_elem.getAttribute(\"Id\")\n            if rel_id.startswith(\"rId\"):\n                try:\n                    max_id = max(max_id, int(rel_id[3:]))\n                except ValueError:\n                    pass\n        return f\"rId{max_id + 1}\"\n\n    def save(self):\n        \"\"\"\n        Save the edited XML back to the file.\n\n        Serializes the DOM tree and writes it back to the original file path,\n        preserving the original encoding (ascii or utf-8).\n        \"\"\"\n        content = self.dom.toxml(encoding=self.encoding)\n        self.xml_path.write_bytes(content)\n\n    def _parse_fragment(self, xml_content):\n        \"\"\"\n        Parse XML fragment and return list of imported nodes.\n\n        Args:\n            xml_content: String containing XML fragment\n\n        Returns:\n            List of defusedxml.minidom.Node objects imported into this document\n\n        Raises:\n            AssertionError: If fragment contains no element nodes\n        \"\"\"\n        # Extract namespace declarations from the root document element\n        root_elem = self.dom.documentElement\n        namespaces = []\n        if root_elem and root_elem.attributes:\n            for i in range(root_elem.attributes.length):\n                attr = root_elem.attributes.item(i)\n                if attr.name.startswith(\"xmlns\"):  # type: ignore\n                    namespaces.append(f'{attr.name}=\"{attr.value}\"')  # type: ignore\n\n        ns_decl = \" \".join(namespaces)\n        wrapper = f\"<root {ns_decl}>{xml_content}</root>\"\n        fragment_doc = defusedxml.minidom.parseString(wrapper)\n        nodes = [\n            self.dom.importNode(child, deep=True)\n            for child in fragment_doc.documentElement.childNodes  # type: ignore\n        ]\n        elements = [n for n in nodes if n.nodeType == n.ELEMENT_NODE]\n        assert elements, \"Fragment must contain at least one element\"\n        return nodes\n\n\ndef _create_line_tracking_parser():\n    \"\"\"\n    Create a SAX parser that tracks line and column numbers for each element.\n\n    Monkey patches the SAX content handler to store the current line and column\n    position from the underlying expat parser onto each element as a parse_position\n    attribute (line, column) tuple.\n\n    Returns:\n        defusedxml.sax.xmlreader.XMLReader: Configured SAX parser\n    \"\"\"\n\n    def set_content_handler(dom_handler):\n        def startElementNS(name, tagName, attrs):\n            orig_start_cb(name, tagName, attrs)\n            cur_elem = dom_handler.elementStack[-1]\n            cur_elem.parse_position = (\n                parser._parser.CurrentLineNumber,  # type: ignore\n                parser._parser.CurrentColumnNumber,  # type: ignore\n            )\n\n        orig_start_cb = dom_handler.startElementNS\n        dom_handler.startElementNS = startElementNS\n        orig_set_content_handler(dom_handler)\n\n    parser = defusedxml.sax.make_parser()\n    orig_set_content_handler = parser.setContentHandler\n    parser.setContentHandler = set_content_handler  # type: ignore\n    return parser\n"
  },
  {
    "path": "document-skills/pdf/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "document-skills/pdf/SKILL.md",
    "content": "---\nname: pdf\ndescription: Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. When Claude needs to fill in a PDF form or programmatically process, generate, or analyze PDF documents at scale.\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# PDF Processing Guide\n\n## Overview\n\nThis guide covers essential PDF processing operations using Python libraries and command-line tools. For advanced features, JavaScript libraries, and detailed examples, see reference.md. If you need to fill out a PDF form, read forms.md and follow its instructions.\n\n## Quick Start\n\n```python\nfrom pypdf import PdfReader, PdfWriter\n\n# Read a PDF\nreader = PdfReader(\"document.pdf\")\nprint(f\"Pages: {len(reader.pages)}\")\n\n# Extract text\ntext = \"\"\nfor page in reader.pages:\n    text += page.extract_text()\n```\n\n## Python Libraries\n\n### pypdf - Basic Operations\n\n#### Merge PDFs\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nwriter = PdfWriter()\nfor pdf_file in [\"doc1.pdf\", \"doc2.pdf\", \"doc3.pdf\"]:\n    reader = PdfReader(pdf_file)\n    for page in reader.pages:\n        writer.add_page(page)\n\nwith open(\"merged.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n#### Split PDF\n```python\nreader = PdfReader(\"input.pdf\")\nfor i, page in enumerate(reader.pages):\n    writer = PdfWriter()\n    writer.add_page(page)\n    with open(f\"page_{i+1}.pdf\", \"wb\") as output:\n        writer.write(output)\n```\n\n#### Extract Metadata\n```python\nreader = PdfReader(\"document.pdf\")\nmeta = reader.metadata\nprint(f\"Title: {meta.title}\")\nprint(f\"Author: {meta.author}\")\nprint(f\"Subject: {meta.subject}\")\nprint(f\"Creator: {meta.creator}\")\n```\n\n#### Rotate Pages\n```python\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\npage = reader.pages[0]\npage.rotate(90)  # Rotate 90 degrees clockwise\nwriter.add_page(page)\n\nwith open(\"rotated.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### pdfplumber - Text and Table Extraction\n\n#### Extract Text with Layout\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for page in pdf.pages:\n        text = page.extract_text()\n        print(text)\n```\n\n#### Extract Tables\n```python\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for i, page in enumerate(pdf.pages):\n        tables = page.extract_tables()\n        for j, table in enumerate(tables):\n            print(f\"Table {j+1} on page {i+1}:\")\n            for row in table:\n                print(row)\n```\n\n#### Advanced Table Extraction\n```python\nimport pandas as pd\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    all_tables = []\n    for page in pdf.pages:\n        tables = page.extract_tables()\n        for table in tables:\n            if table:  # Check if table is not empty\n                df = pd.DataFrame(table[1:], columns=table[0])\n                all_tables.append(df)\n\n# Combine all tables\nif all_tables:\n    combined_df = pd.concat(all_tables, ignore_index=True)\n    combined_df.to_excel(\"extracted_tables.xlsx\", index=False)\n```\n\n### reportlab - Create PDFs\n\n#### Basic PDF Creation\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.pdfgen import canvas\n\nc = canvas.Canvas(\"hello.pdf\", pagesize=letter)\nwidth, height = letter\n\n# Add text\nc.drawString(100, height - 100, \"Hello World!\")\nc.drawString(100, height - 120, \"This is a PDF created with reportlab\")\n\n# Add a line\nc.line(100, height - 140, 400, height - 140)\n\n# Save\nc.save()\n```\n\n#### Create PDF with Multiple Pages\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak\nfrom reportlab.lib.styles import getSampleStyleSheet\n\ndoc = SimpleDocTemplate(\"report.pdf\", pagesize=letter)\nstyles = getSampleStyleSheet()\nstory = []\n\n# Add content\ntitle = Paragraph(\"Report Title\", styles['Title'])\nstory.append(title)\nstory.append(Spacer(1, 12))\n\nbody = Paragraph(\"This is the body of the report. \" * 20, styles['Normal'])\nstory.append(body)\nstory.append(PageBreak())\n\n# Page 2\nstory.append(Paragraph(\"Page 2\", styles['Heading1']))\nstory.append(Paragraph(\"Content for page 2\", styles['Normal']))\n\n# Build PDF\ndoc.build(story)\n```\n\n## Command-Line Tools\n\n### pdftotext (poppler-utils)\n```bash\n# Extract text\npdftotext input.pdf output.txt\n\n# Extract text preserving layout\npdftotext -layout input.pdf output.txt\n\n# Extract specific pages\npdftotext -f 1 -l 5 input.pdf output.txt  # Pages 1-5\n```\n\n### qpdf\n```bash\n# Merge PDFs\nqpdf --empty --pages file1.pdf file2.pdf -- merged.pdf\n\n# Split pages\nqpdf input.pdf --pages . 1-5 -- pages1-5.pdf\nqpdf input.pdf --pages . 6-10 -- pages6-10.pdf\n\n# Rotate pages\nqpdf input.pdf output.pdf --rotate=+90:1  # Rotate page 1 by 90 degrees\n\n# Remove password\nqpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf\n```\n\n### pdftk (if available)\n```bash\n# Merge\npdftk file1.pdf file2.pdf cat output merged.pdf\n\n# Split\npdftk input.pdf burst\n\n# Rotate\npdftk input.pdf rotate 1east output rotated.pdf\n```\n\n## Common Tasks\n\n### Extract Text from Scanned PDFs\n```python\n# Requires: pip install pytesseract pdf2image\nimport pytesseract\nfrom pdf2image import convert_from_path\n\n# Convert PDF to images\nimages = convert_from_path('scanned.pdf')\n\n# OCR each page\ntext = \"\"\nfor i, image in enumerate(images):\n    text += f\"Page {i+1}:\\n\"\n    text += pytesseract.image_to_string(image)\n    text += \"\\n\\n\"\n\nprint(text)\n```\n\n### Add Watermark\n```python\nfrom pypdf import PdfReader, PdfWriter\n\n# Create watermark (or load existing)\nwatermark = PdfReader(\"watermark.pdf\").pages[0]\n\n# Apply to all pages\nreader = PdfReader(\"document.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    page.merge_page(watermark)\n    writer.add_page(page)\n\nwith open(\"watermarked.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### Extract Images\n```bash\n# Using pdfimages (poppler-utils)\npdfimages -j input.pdf output_prefix\n\n# This extracts all images as output_prefix-000.jpg, output_prefix-001.jpg, etc.\n```\n\n### Password Protection\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    writer.add_page(page)\n\n# Add password\nwriter.encrypt(\"userpassword\", \"ownerpassword\")\n\nwith open(\"encrypted.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Quick Reference\n\n| Task | Best Tool | Command/Code |\n|------|-----------|--------------|\n| Merge PDFs | pypdf | `writer.add_page(page)` |\n| Split PDFs | pypdf | One page per file |\n| Extract text | pdfplumber | `page.extract_text()` |\n| Extract tables | pdfplumber | `page.extract_tables()` |\n| Create PDFs | reportlab | Canvas or Platypus |\n| Command line merge | qpdf | `qpdf --empty --pages ...` |\n| OCR scanned PDFs | pytesseract | Convert to image first |\n| Fill PDF forms | pdf-lib or pypdf (see forms.md) | See forms.md |\n\n## Next Steps\n\n- For advanced pypdfium2 usage, see reference.md\n- For JavaScript libraries (pdf-lib), see reference.md\n- If you need to fill out a PDF form, follow the instructions in forms.md\n- For troubleshooting guides, see reference.md\n"
  },
  {
    "path": "document-skills/pdf/forms.md",
    "content": "**CRITICAL: You MUST complete these steps in order. Do not skip ahead to writing code.**\n\nIf you need to fill out a PDF form, first check to see if the PDF has fillable form fields. Run this script from this file's directory:\n `python scripts/check_fillable_fields <file.pdf>`, and depending on the result go to either the \"Fillable fields\" or \"Non-fillable fields\" and follow those instructions.\n\n# Fillable fields\nIf the PDF has fillable form fields:\n- Run this script from this file's directory: `python scripts/extract_form_field_info.py <input.pdf> <field_info.json>`. It will create a JSON file with a list of fields in this format:\n```\n[\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"rect\": ([left, bottom, right, top] bounding box in PDF coordinates, y=0 is the bottom of the page),\n    \"type\": (\"text\", \"checkbox\", \"radio_group\", or \"choice\"),\n  },\n  // Checkboxes have \"checked_value\" and \"unchecked_value\" properties:\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"checkbox\",\n    \"checked_value\": (Set the field to this value to check the checkbox),\n    \"unchecked_value\": (Set the field to this value to uncheck the checkbox),\n  },\n  // Radio groups have a \"radio_options\" list with the possible choices.\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"radio_group\",\n    \"radio_options\": [\n      {\n        \"value\": (set the field to this value to select this radio option),\n        \"rect\": (bounding box for the radio button for this option)\n      },\n      // Other radio options\n    ]\n  },\n  // Multiple choice fields have a \"choice_options\" list with the possible choices:\n  {\n    \"field_id\": (unique ID for the field),\n    \"page\": (page number, 1-based),\n    \"type\": \"choice\",\n    \"choice_options\": [\n      {\n        \"value\": (set the field to this value to select this option),\n        \"text\": (display text of the option)\n      },\n      // Other choice options\n    ],\n  }\n]\n```\n- Convert the PDF to PNGs (one image for each page) with this script (run from this file's directory):\n`python scripts/convert_pdf_to_images.py <file.pdf> <output_directory>`\nThen analyze the images to determine the purpose of each form field (make sure to convert the bounding box PDF coordinates to image coordinates).\n- Create a `field_values.json` file in this format with the values to be entered for each field:\n```\n[\n  {\n    \"field_id\": \"last_name\", // Must match the field_id from `extract_form_field_info.py`\n    \"description\": \"The user's last name\",\n    \"page\": 1, // Must match the \"page\" value in field_info.json\n    \"value\": \"Simpson\"\n  },\n  {\n    \"field_id\": \"Checkbox12\",\n    \"description\": \"Checkbox to be checked if the user is 18 or over\",\n    \"page\": 1,\n    \"value\": \"/On\" // If this is a checkbox, use its \"checked_value\" value to check it. If it's a radio button group, use one of the \"value\" values in \"radio_options\".\n  },\n  // more fields\n]\n```\n- Run the `fill_fillable_fields.py` script from this file's directory to create a filled-in PDF:\n`python scripts/fill_fillable_fields.py <input pdf> <field_values.json> <output pdf>`\nThis script will verify that the field IDs and values you provide are valid; if it prints error messages, correct the appropriate fields and try again.\n\n# Non-fillable fields\nIf the PDF doesn't have fillable form fields, you'll need to visually determine where the data should be added and create text annotations. Follow the below steps *exactly*. You MUST perform all of these steps to ensure that the the form is accurately completed. Details for each step are below.\n- Convert the PDF to PNG images and determine field bounding boxes.\n- Create a JSON file with field information and validation images showing the bounding boxes.\n- Validate the the bounding boxes.\n- Use the bounding boxes to fill in the form.\n\n## Step 1: Visual Analysis (REQUIRED)\n- Convert the PDF to PNG images. Run this script from this file's directory:\n`python scripts/convert_pdf_to_images.py <file.pdf> <output_directory>`\nThe script will create a PNG image for each page in the PDF.\n- Carefully examine each PNG image and identify all form fields and areas where the user should enter data. For each form field where the user should enter text, determine bounding boxes for both the form field label, and the area where the user should enter text. The label and entry bounding boxes MUST NOT INTERSECT; the text entry box should only include the area where data should be entered. Usually this area will be immediately to the side, above, or below its label. Entry bounding boxes must be tall and wide enough to contain their text.\n\nThese are some examples of form structures that you might see:\n\n*Label inside box*\n```\n┌────────────────────────┐\n│ Name:                  │\n└────────────────────────┘\n```\nThe input area should be to the right of the \"Name\" label and extend to the edge of the box.\n\n*Label before line*\n```\nEmail: _______________________\n```\nThe input area should be above the line and include its entire width.\n\n*Label under line*\n```\n_________________________\nName\n```\nThe input area should be above the line and include the entire width of the line. This is common for signature and date fields.\n\n*Label above line*\n```\nPlease enter any special requests:\n________________________________________________\n```\nThe input area should extend from the bottom of the label to the line, and should include the entire width of the line.\n\n*Checkboxes*\n```\nAre you a US citizen? Yes □  No □\n```\nFor checkboxes:\n- Look for small square boxes (□) - these are the actual checkboxes to target. They may be to the left or right of their labels.\n- Distinguish between label text (\"Yes\", \"No\") and the clickable checkbox squares.\n- The entry bounding box should cover ONLY the small square, not the text label.\n\n### Step 2: Create fields.json and validation images (REQUIRED)\n- Create a file named `fields.json` with information for the form fields and bounding boxes in this format:\n```\n{\n  \"pages\": [\n    {\n      \"page_number\": 1,\n      \"image_width\": (first page image width in pixels),\n      \"image_height\": (first page image height in pixels),\n    },\n    {\n      \"page_number\": 2,\n      \"image_width\": (second page image width in pixels),\n      \"image_height\": (second page image height in pixels),\n    }\n    // additional pages\n  ],\n  \"form_fields\": [\n    // Example for a text field.\n    {\n      \"page_number\": 1,\n      \"description\": \"The user's last name should be entered here\",\n      // Bounding boxes are [left, top, right, bottom]. The bounding boxes for the label and text entry should not overlap.\n      \"field_label\": \"Last name\",\n      \"label_bounding_box\": [30, 125, 95, 142],\n      \"entry_bounding_box\": [100, 125, 280, 142],\n      \"entry_text\": {\n        \"text\": \"Johnson\", // This text will be added as an annotation at the entry_bounding_box location\n        \"font_size\": 14, // optional, defaults to 14\n        \"font_color\": \"000000\", // optional, RRGGBB format, defaults to 000000 (black)\n      }\n    },\n    // Example for a checkbox. TARGET THE SQUARE for the entry bounding box, NOT THE TEXT\n    {\n      \"page_number\": 2,\n      \"description\": \"Checkbox that should be checked if the user is over 18\",\n      \"entry_bounding_box\": [140, 525, 155, 540],  // Small box over checkbox square\n      \"field_label\": \"Yes\",\n      \"label_bounding_box\": [100, 525, 132, 540],  // Box containing \"Yes\" text\n      // Use \"X\" to check a checkbox.\n      \"entry_text\": {\n        \"text\": \"X\",\n      }\n    }\n    // additional form field entries\n  ]\n}\n```\n\nCreate validation images by running this script from this file's directory for each page:\n`python scripts/create_validation_image.py <page_number> <path_to_fields.json> <input_image_path> <output_image_path>\n\nThe validation images will have red rectangles where text should be entered, and blue rectangles covering label text.\n\n### Step 3: Validate Bounding Boxes (REQUIRED)\n#### Automated intersection check\n- Verify that none of bounding boxes intersect and that the entry bounding boxes are tall enough by checking the fields.json file with the `check_bounding_boxes.py` script (run from this file's directory):\n`python scripts/check_bounding_boxes.py <JSON file>`\n\nIf there are errors, reanalyze the relevant fields, adjust the bounding boxes, and iterate until there are no remaining errors. Remember: label (blue) bounding boxes should contain text labels, entry (red) boxes should not.\n\n#### Manual image inspection\n**CRITICAL: Do not proceed without visually inspecting validation images**\n- Red rectangles must ONLY cover input areas\n- Red rectangles MUST NOT contain any text\n- Blue rectangles should contain label text\n- For checkboxes:\n  - Red rectangle MUST be centered on the checkbox square\n  - Blue rectangle should cover the text label for the checkbox\n\n- If any rectangles look wrong, fix fields.json, regenerate the validation images, and verify again. Repeat this process until the bounding boxes are fully accurate.\n\n\n### Step 4: Add annotations to the PDF\nRun this script from this file's directory to create a filled-out PDF using the information in fields.json:\n`python scripts/fill_pdf_form_with_annotations.py <input_pdf_path> <path_to_fields.json> <output_pdf_path>\n"
  },
  {
    "path": "document-skills/pdf/reference.md",
    "content": "# PDF Processing Advanced Reference\n\nThis document contains advanced PDF processing features, detailed examples, and additional libraries not covered in the main skill instructions.\n\n## pypdfium2 Library (Apache/BSD License)\n\n### Overview\npypdfium2 is a Python binding for PDFium (Chromium's PDF library). It's excellent for fast PDF rendering, image generation, and serves as a PyMuPDF replacement.\n\n### Render PDF to Images\n```python\nimport pypdfium2 as pdfium\nfrom PIL import Image\n\n# Load PDF\npdf = pdfium.PdfDocument(\"document.pdf\")\n\n# Render page to image\npage = pdf[0]  # First page\nbitmap = page.render(\n    scale=2.0,  # Higher resolution\n    rotation=0  # No rotation\n)\n\n# Convert to PIL Image\nimg = bitmap.to_pil()\nimg.save(\"page_1.png\", \"PNG\")\n\n# Process multiple pages\nfor i, page in enumerate(pdf):\n    bitmap = page.render(scale=1.5)\n    img = bitmap.to_pil()\n    img.save(f\"page_{i+1}.jpg\", \"JPEG\", quality=90)\n```\n\n### Extract Text with pypdfium2\n```python\nimport pypdfium2 as pdfium\n\npdf = pdfium.PdfDocument(\"document.pdf\")\nfor i, page in enumerate(pdf):\n    text = page.get_text()\n    print(f\"Page {i+1} text length: {len(text)} chars\")\n```\n\n## JavaScript Libraries\n\n### pdf-lib (MIT License)\n\npdf-lib is a powerful JavaScript library for creating and modifying PDF documents in any JavaScript environment.\n\n#### Load and Manipulate Existing PDF\n```javascript\nimport { PDFDocument } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function manipulatePDF() {\n    // Load existing PDF\n    const existingPdfBytes = fs.readFileSync('input.pdf');\n    const pdfDoc = await PDFDocument.load(existingPdfBytes);\n\n    // Get page count\n    const pageCount = pdfDoc.getPageCount();\n    console.log(`Document has ${pageCount} pages`);\n\n    // Add new page\n    const newPage = pdfDoc.addPage([600, 400]);\n    newPage.drawText('Added by pdf-lib', {\n        x: 100,\n        y: 300,\n        size: 16\n    });\n\n    // Save modified PDF\n    const pdfBytes = await pdfDoc.save();\n    fs.writeFileSync('modified.pdf', pdfBytes);\n}\n```\n\n#### Create Complex PDFs from Scratch\n```javascript\nimport { PDFDocument, rgb, StandardFonts } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function createPDF() {\n    const pdfDoc = await PDFDocument.create();\n\n    // Add fonts\n    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);\n    const helveticaBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\n\n    // Add page\n    const page = pdfDoc.addPage([595, 842]); // A4 size\n    const { width, height } = page.getSize();\n\n    // Add text with styling\n    page.drawText('Invoice #12345', {\n        x: 50,\n        y: height - 50,\n        size: 18,\n        font: helveticaBold,\n        color: rgb(0.2, 0.2, 0.8)\n    });\n\n    // Add rectangle (header background)\n    page.drawRectangle({\n        x: 40,\n        y: height - 100,\n        width: width - 80,\n        height: 30,\n        color: rgb(0.9, 0.9, 0.9)\n    });\n\n    // Add table-like content\n    const items = [\n        ['Item', 'Qty', 'Price', 'Total'],\n        ['Widget', '2', '$50', '$100'],\n        ['Gadget', '1', '$75', '$75']\n    ];\n\n    let yPos = height - 150;\n    items.forEach(row => {\n        let xPos = 50;\n        row.forEach(cell => {\n            page.drawText(cell, {\n                x: xPos,\n                y: yPos,\n                size: 12,\n                font: helveticaFont\n            });\n            xPos += 120;\n        });\n        yPos -= 25;\n    });\n\n    const pdfBytes = await pdfDoc.save();\n    fs.writeFileSync('created.pdf', pdfBytes);\n}\n```\n\n#### Advanced Merge and Split Operations\n```javascript\nimport { PDFDocument } from 'pdf-lib';\nimport fs from 'fs';\n\nasync function mergePDFs() {\n    // Create new document\n    const mergedPdf = await PDFDocument.create();\n\n    // Load source PDFs\n    const pdf1Bytes = fs.readFileSync('doc1.pdf');\n    const pdf2Bytes = fs.readFileSync('doc2.pdf');\n\n    const pdf1 = await PDFDocument.load(pdf1Bytes);\n    const pdf2 = await PDFDocument.load(pdf2Bytes);\n\n    // Copy pages from first PDF\n    const pdf1Pages = await mergedPdf.copyPages(pdf1, pdf1.getPageIndices());\n    pdf1Pages.forEach(page => mergedPdf.addPage(page));\n\n    // Copy specific pages from second PDF (pages 0, 2, 4)\n    const pdf2Pages = await mergedPdf.copyPages(pdf2, [0, 2, 4]);\n    pdf2Pages.forEach(page => mergedPdf.addPage(page));\n\n    const mergedPdfBytes = await mergedPdf.save();\n    fs.writeFileSync('merged.pdf', mergedPdfBytes);\n}\n```\n\n### pdfjs-dist (Apache License)\n\nPDF.js is Mozilla's JavaScript library for rendering PDFs in the browser.\n\n#### Basic PDF Loading and Rendering\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\n// Configure worker (important for performance)\npdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.js';\n\nasync function renderPDF() {\n    // Load PDF\n    const loadingTask = pdfjsLib.getDocument('document.pdf');\n    const pdf = await loadingTask.promise;\n\n    console.log(`Loaded PDF with ${pdf.numPages} pages`);\n\n    // Get first page\n    const page = await pdf.getPage(1);\n    const viewport = page.getViewport({ scale: 1.5 });\n\n    // Render to canvas\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    canvas.height = viewport.height;\n    canvas.width = viewport.width;\n\n    const renderContext = {\n        canvasContext: context,\n        viewport: viewport\n    };\n\n    await page.render(renderContext).promise;\n    document.body.appendChild(canvas);\n}\n```\n\n#### Extract Text with Coordinates\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\nasync function extractText() {\n    const loadingTask = pdfjsLib.getDocument('document.pdf');\n    const pdf = await loadingTask.promise;\n\n    let fullText = '';\n\n    // Extract text from all pages\n    for (let i = 1; i <= pdf.numPages; i++) {\n        const page = await pdf.getPage(i);\n        const textContent = await page.getTextContent();\n\n        const pageText = textContent.items\n            .map(item => item.str)\n            .join(' ');\n\n        fullText += `\\n--- Page ${i} ---\\n${pageText}`;\n\n        // Get text with coordinates for advanced processing\n        const textWithCoords = textContent.items.map(item => ({\n            text: item.str,\n            x: item.transform[4],\n            y: item.transform[5],\n            width: item.width,\n            height: item.height\n        }));\n    }\n\n    console.log(fullText);\n    return fullText;\n}\n```\n\n#### Extract Annotations and Forms\n```javascript\nimport * as pdfjsLib from 'pdfjs-dist';\n\nasync function extractAnnotations() {\n    const loadingTask = pdfjsLib.getDocument('annotated.pdf');\n    const pdf = await loadingTask.promise;\n\n    for (let i = 1; i <= pdf.numPages; i++) {\n        const page = await pdf.getPage(i);\n        const annotations = await page.getAnnotations();\n\n        annotations.forEach(annotation => {\n            console.log(`Annotation type: ${annotation.subtype}`);\n            console.log(`Content: ${annotation.contents}`);\n            console.log(`Coordinates: ${JSON.stringify(annotation.rect)}`);\n        });\n    }\n}\n```\n\n## Advanced Command-Line Operations\n\n### poppler-utils Advanced Features\n\n#### Extract Text with Bounding Box Coordinates\n```bash\n# Extract text with bounding box coordinates (essential for structured data)\npdftotext -bbox-layout document.pdf output.xml\n\n# The XML output contains precise coordinates for each text element\n```\n\n#### Advanced Image Conversion\n```bash\n# Convert to PNG images with specific resolution\npdftoppm -png -r 300 document.pdf output_prefix\n\n# Convert specific page range with high resolution\npdftoppm -png -r 600 -f 1 -l 3 document.pdf high_res_pages\n\n# Convert to JPEG with quality setting\npdftoppm -jpeg -jpegopt quality=85 -r 200 document.pdf jpeg_output\n```\n\n#### Extract Embedded Images\n```bash\n# Extract all embedded images with metadata\npdfimages -j -p document.pdf page_images\n\n# List image info without extracting\npdfimages -list document.pdf\n\n# Extract images in their original format\npdfimages -all document.pdf images/img\n```\n\n### qpdf Advanced Features\n\n#### Complex Page Manipulation\n```bash\n# Split PDF into groups of pages\nqpdf --split-pages=3 input.pdf output_group_%02d.pdf\n\n# Extract specific pages with complex ranges\nqpdf input.pdf --pages input.pdf 1,3-5,8,10-end -- extracted.pdf\n\n# Merge specific pages from multiple PDFs\nqpdf --empty --pages doc1.pdf 1-3 doc2.pdf 5-7 doc3.pdf 2,4 -- combined.pdf\n```\n\n#### PDF Optimization and Repair\n```bash\n# Optimize PDF for web (linearize for streaming)\nqpdf --linearize input.pdf optimized.pdf\n\n# Remove unused objects and compress\nqpdf --optimize-level=all input.pdf compressed.pdf\n\n# Attempt to repair corrupted PDF structure\nqpdf --check input.pdf\nqpdf --fix-qdf damaged.pdf repaired.pdf\n\n# Show detailed PDF structure for debugging\nqpdf --show-all-pages input.pdf > structure.txt\n```\n\n#### Advanced Encryption\n```bash\n# Add password protection with specific permissions\nqpdf --encrypt user_pass owner_pass 256 --print=none --modify=none -- input.pdf encrypted.pdf\n\n# Check encryption status\nqpdf --show-encryption encrypted.pdf\n\n# Remove password protection (requires password)\nqpdf --password=secret123 --decrypt encrypted.pdf decrypted.pdf\n```\n\n## Advanced Python Techniques\n\n### pdfplumber Advanced Features\n\n#### Extract Text with Precise Coordinates\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    page = pdf.pages[0]\n    \n    # Extract all text with coordinates\n    chars = page.chars\n    for char in chars[:10]:  # First 10 characters\n        print(f\"Char: '{char['text']}' at x:{char['x0']:.1f} y:{char['y0']:.1f}\")\n    \n    # Extract text by bounding box (left, top, right, bottom)\n    bbox_text = page.within_bbox((100, 100, 400, 200)).extract_text()\n```\n\n#### Advanced Table Extraction with Custom Settings\n```python\nimport pdfplumber\nimport pandas as pd\n\nwith pdfplumber.open(\"complex_table.pdf\") as pdf:\n    page = pdf.pages[0]\n    \n    # Extract tables with custom settings for complex layouts\n    table_settings = {\n        \"vertical_strategy\": \"lines\",\n        \"horizontal_strategy\": \"lines\",\n        \"snap_tolerance\": 3,\n        \"intersection_tolerance\": 15\n    }\n    tables = page.extract_tables(table_settings)\n    \n    # Visual debugging for table extraction\n    img = page.to_image(resolution=150)\n    img.save(\"debug_layout.png\")\n```\n\n### reportlab Advanced Features\n\n#### Create Professional Reports with Tables\n```python\nfrom reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph\nfrom reportlab.lib.styles import getSampleStyleSheet\nfrom reportlab.lib import colors\n\n# Sample data\ndata = [\n    ['Product', 'Q1', 'Q2', 'Q3', 'Q4'],\n    ['Widgets', '120', '135', '142', '158'],\n    ['Gadgets', '85', '92', '98', '105']\n]\n\n# Create PDF with table\ndoc = SimpleDocTemplate(\"report.pdf\")\nelements = []\n\n# Add title\nstyles = getSampleStyleSheet()\ntitle = Paragraph(\"Quarterly Sales Report\", styles['Title'])\nelements.append(title)\n\n# Add table with advanced styling\ntable = Table(data)\ntable.setStyle(TableStyle([\n    ('BACKGROUND', (0, 0), (-1, 0), colors.grey),\n    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),\n    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),\n    ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),\n    ('FONTSIZE', (0, 0), (-1, 0), 14),\n    ('BOTTOMPADDING', (0, 0), (-1, 0), 12),\n    ('BACKGROUND', (0, 1), (-1, -1), colors.beige),\n    ('GRID', (0, 0), (-1, -1), 1, colors.black)\n]))\nelements.append(table)\n\ndoc.build(elements)\n```\n\n## Complex Workflows\n\n### Extract Figures/Images from PDF\n\n#### Method 1: Using pdfimages (fastest)\n```bash\n# Extract all images with original quality\npdfimages -all document.pdf images/img\n```\n\n#### Method 2: Using pypdfium2 + Image Processing\n```python\nimport pypdfium2 as pdfium\nfrom PIL import Image\nimport numpy as np\n\ndef extract_figures(pdf_path, output_dir):\n    pdf = pdfium.PdfDocument(pdf_path)\n    \n    for page_num, page in enumerate(pdf):\n        # Render high-resolution page\n        bitmap = page.render(scale=3.0)\n        img = bitmap.to_pil()\n        \n        # Convert to numpy for processing\n        img_array = np.array(img)\n        \n        # Simple figure detection (non-white regions)\n        mask = np.any(img_array != [255, 255, 255], axis=2)\n        \n        # Find contours and extract bounding boxes\n        # (This is simplified - real implementation would need more sophisticated detection)\n        \n        # Save detected figures\n        # ... implementation depends on specific needs\n```\n\n### Batch PDF Processing with Error Handling\n```python\nimport os\nimport glob\nfrom pypdf import PdfReader, PdfWriter\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\ndef batch_process_pdfs(input_dir, operation='merge'):\n    pdf_files = glob.glob(os.path.join(input_dir, \"*.pdf\"))\n    \n    if operation == 'merge':\n        writer = PdfWriter()\n        for pdf_file in pdf_files:\n            try:\n                reader = PdfReader(pdf_file)\n                for page in reader.pages:\n                    writer.add_page(page)\n                logger.info(f\"Processed: {pdf_file}\")\n            except Exception as e:\n                logger.error(f\"Failed to process {pdf_file}: {e}\")\n                continue\n        \n        with open(\"batch_merged.pdf\", \"wb\") as output:\n            writer.write(output)\n    \n    elif operation == 'extract_text':\n        for pdf_file in pdf_files:\n            try:\n                reader = PdfReader(pdf_file)\n                text = \"\"\n                for page in reader.pages:\n                    text += page.extract_text()\n                \n                output_file = pdf_file.replace('.pdf', '.txt')\n                with open(output_file, 'w', encoding='utf-8') as f:\n                    f.write(text)\n                logger.info(f\"Extracted text from: {pdf_file}\")\n                \n            except Exception as e:\n                logger.error(f\"Failed to extract text from {pdf_file}: {e}\")\n                continue\n```\n\n### Advanced PDF Cropping\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\n\n# Crop page (left, bottom, right, top in points)\npage = reader.pages[0]\npage.mediabox.left = 50\npage.mediabox.bottom = 50\npage.mediabox.right = 550\npage.mediabox.top = 750\n\nwriter.add_page(page)\nwith open(\"cropped.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Performance Optimization Tips\n\n### 1. For Large PDFs\n- Use streaming approaches instead of loading entire PDF in memory\n- Use `qpdf --split-pages` for splitting large files\n- Process pages individually with pypdfium2\n\n### 2. For Text Extraction\n- `pdftotext -bbox-layout` is fastest for plain text extraction\n- Use pdfplumber for structured data and tables\n- Avoid `pypdf.extract_text()` for very large documents\n\n### 3. For Image Extraction\n- `pdfimages` is much faster than rendering pages\n- Use low resolution for previews, high resolution for final output\n\n### 4. For Form Filling\n- pdf-lib maintains form structure better than most alternatives\n- Pre-validate form fields before processing\n\n### 5. Memory Management\n```python\n# Process PDFs in chunks\ndef process_large_pdf(pdf_path, chunk_size=10):\n    reader = PdfReader(pdf_path)\n    total_pages = len(reader.pages)\n    \n    for start_idx in range(0, total_pages, chunk_size):\n        end_idx = min(start_idx + chunk_size, total_pages)\n        writer = PdfWriter()\n        \n        for i in range(start_idx, end_idx):\n            writer.add_page(reader.pages[i])\n        \n        # Process chunk\n        with open(f\"chunk_{start_idx//chunk_size}.pdf\", \"wb\") as output:\n            writer.write(output)\n```\n\n## Troubleshooting Common Issues\n\n### Encrypted PDFs\n```python\n# Handle password-protected PDFs\nfrom pypdf import PdfReader\n\ntry:\n    reader = PdfReader(\"encrypted.pdf\")\n    if reader.is_encrypted:\n        reader.decrypt(\"password\")\nexcept Exception as e:\n    print(f\"Failed to decrypt: {e}\")\n```\n\n### Corrupted PDFs\n```bash\n# Use qpdf to repair\nqpdf --check corrupted.pdf\nqpdf --replace-input corrupted.pdf\n```\n\n### Text Extraction Issues\n```python\n# Fallback to OCR for scanned PDFs\nimport pytesseract\nfrom pdf2image import convert_from_path\n\ndef extract_text_with_ocr(pdf_path):\n    images = convert_from_path(pdf_path)\n    text = \"\"\n    for i, image in enumerate(images):\n        text += pytesseract.image_to_string(image)\n    return text\n```\n\n## License Information\n\n- **pypdf**: BSD License\n- **pdfplumber**: MIT License\n- **pypdfium2**: Apache/BSD License\n- **reportlab**: BSD License\n- **poppler-utils**: GPL-2 License\n- **qpdf**: Apache License\n- **pdf-lib**: MIT License\n- **pdfjs-dist**: Apache License"
  },
  {
    "path": "document-skills/pdf/scripts/check_bounding_boxes.py",
    "content": "from dataclasses import dataclass\nimport json\nimport sys\n\n\n# Script to check that the `fields.json` file that Claude creates when analyzing PDFs\n# does not have overlapping bounding boxes. See forms.md.\n\n\n@dataclass\nclass RectAndField:\n    rect: list[float]\n    rect_type: str\n    field: dict\n\n\n# Returns a list of messages that are printed to stdout for Claude to read.\ndef get_bounding_box_messages(fields_json_stream) -> list[str]:\n    messages = []\n    fields = json.load(fields_json_stream)\n    messages.append(f\"Read {len(fields['form_fields'])} fields\")\n\n    def rects_intersect(r1, r2):\n        disjoint_horizontal = r1[0] >= r2[2] or r1[2] <= r2[0]\n        disjoint_vertical = r1[1] >= r2[3] or r1[3] <= r2[1]\n        return not (disjoint_horizontal or disjoint_vertical)\n\n    rects_and_fields = []\n    for f in fields[\"form_fields\"]:\n        rects_and_fields.append(RectAndField(f[\"label_bounding_box\"], \"label\", f))\n        rects_and_fields.append(RectAndField(f[\"entry_bounding_box\"], \"entry\", f))\n\n    has_error = False\n    for i, ri in enumerate(rects_and_fields):\n        # This is O(N^2); we can optimize if it becomes a problem.\n        for j in range(i + 1, len(rects_and_fields)):\n            rj = rects_and_fields[j]\n            if ri.field[\"page_number\"] == rj.field[\"page_number\"] and rects_intersect(ri.rect, rj.rect):\n                has_error = True\n                if ri.field is rj.field:\n                    messages.append(f\"FAILURE: intersection between label and entry bounding boxes for `{ri.field['description']}` ({ri.rect}, {rj.rect})\")\n                else:\n                    messages.append(f\"FAILURE: intersection between {ri.rect_type} bounding box for `{ri.field['description']}` ({ri.rect}) and {rj.rect_type} bounding box for `{rj.field['description']}` ({rj.rect})\")\n                if len(messages) >= 20:\n                    messages.append(\"Aborting further checks; fix bounding boxes and try again\")\n                    return messages\n        if ri.rect_type == \"entry\":\n            if \"entry_text\" in ri.field:\n                font_size = ri.field[\"entry_text\"].get(\"font_size\", 14)\n                entry_height = ri.rect[3] - ri.rect[1]\n                if entry_height < font_size:\n                    has_error = True\n                    messages.append(f\"FAILURE: entry bounding box height ({entry_height}) for `{ri.field['description']}` is too short for the text content (font size: {font_size}). Increase the box height or decrease the font size.\")\n                    if len(messages) >= 20:\n                        messages.append(\"Aborting further checks; fix bounding boxes and try again\")\n                        return messages\n\n    if not has_error:\n        messages.append(\"SUCCESS: All bounding boxes are valid\")\n    return messages\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        print(\"Usage: check_bounding_boxes.py [fields.json]\")\n        sys.exit(1)\n    # Input file should be in the `fields.json` format described in forms.md.\n    with open(sys.argv[1]) as f:\n        messages = get_bounding_box_messages(f)\n    for msg in messages:\n        print(msg)\n"
  },
  {
    "path": "document-skills/pdf/scripts/check_bounding_boxes_test.py",
    "content": "import unittest\nimport json\nimport io\nfrom check_bounding_boxes import get_bounding_box_messages\n\n\n# Currently this is not run automatically in CI; it's just for documentation and manual checking.\nclass TestGetBoundingBoxMessages(unittest.TestCase):\n    \n    def create_json_stream(self, data):\n        \"\"\"Helper to create a JSON stream from data\"\"\"\n        return io.StringIO(json.dumps(data))\n    \n    def test_no_intersections(self):\n        \"\"\"Test case with no bounding box intersections\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 30]\n                },\n                {\n                    \"description\": \"Email\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 40, 50, 60],\n                    \"entry_bounding_box\": [60, 40, 150, 60]\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"SUCCESS\" in msg for msg in messages))\n        self.assertFalse(any(\"FAILURE\" in msg for msg in messages))\n    \n    def test_label_entry_intersection_same_field(self):\n        \"\"\"Test intersection between label and entry of the same field\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 60, 30],\n                    \"entry_bounding_box\": [50, 10, 150, 30]  # Overlaps with label\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"FAILURE\" in msg and \"intersection\" in msg for msg in messages))\n        self.assertFalse(any(\"SUCCESS\" in msg for msg in messages))\n    \n    def test_intersection_between_different_fields(self):\n        \"\"\"Test intersection between bounding boxes of different fields\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 30]\n                },\n                {\n                    \"description\": \"Email\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [40, 20, 80, 40],  # Overlaps with Name's boxes\n                    \"entry_bounding_box\": [160, 10, 250, 30]\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"FAILURE\" in msg and \"intersection\" in msg for msg in messages))\n        self.assertFalse(any(\"SUCCESS\" in msg for msg in messages))\n    \n    def test_different_pages_no_intersection(self):\n        \"\"\"Test that boxes on different pages don't count as intersecting\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 30]\n                },\n                {\n                    \"description\": \"Email\",\n                    \"page_number\": 2,\n                    \"label_bounding_box\": [10, 10, 50, 30],  # Same coordinates but different page\n                    \"entry_bounding_box\": [60, 10, 150, 30]\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"SUCCESS\" in msg for msg in messages))\n        self.assertFalse(any(\"FAILURE\" in msg for msg in messages))\n    \n    def test_entry_height_too_small(self):\n        \"\"\"Test that entry box height is checked against font size\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 20],  # Height is 10\n                    \"entry_text\": {\n                        \"font_size\": 14  # Font size larger than height\n                    }\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"FAILURE\" in msg and \"height\" in msg for msg in messages))\n        self.assertFalse(any(\"SUCCESS\" in msg for msg in messages))\n    \n    def test_entry_height_adequate(self):\n        \"\"\"Test that adequate entry box height passes\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 30],  # Height is 20\n                    \"entry_text\": {\n                        \"font_size\": 14  # Font size smaller than height\n                    }\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"SUCCESS\" in msg for msg in messages))\n        self.assertFalse(any(\"FAILURE\" in msg for msg in messages))\n    \n    def test_default_font_size(self):\n        \"\"\"Test that default font size is used when not specified\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 20],  # Height is 10\n                    \"entry_text\": {}  # No font_size specified, should use default 14\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"FAILURE\" in msg and \"height\" in msg for msg in messages))\n        self.assertFalse(any(\"SUCCESS\" in msg for msg in messages))\n    \n    def test_no_entry_text(self):\n        \"\"\"Test that missing entry_text doesn't cause height check\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [60, 10, 150, 20]  # Small height but no entry_text\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"SUCCESS\" in msg for msg in messages))\n        self.assertFalse(any(\"FAILURE\" in msg for msg in messages))\n    \n    def test_multiple_errors_limit(self):\n        \"\"\"Test that error messages are limited to prevent excessive output\"\"\"\n        fields = []\n        # Create many overlapping fields\n        for i in range(25):\n            fields.append({\n                \"description\": f\"Field{i}\",\n                \"page_number\": 1,\n                \"label_bounding_box\": [10, 10, 50, 30],  # All overlap\n                \"entry_bounding_box\": [20, 15, 60, 35]   # All overlap\n            })\n        \n        data = {\"form_fields\": fields}\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        # Should abort after ~20 messages\n        self.assertTrue(any(\"Aborting\" in msg for msg in messages))\n        # Should have some FAILURE messages but not hundreds\n        failure_count = sum(1 for msg in messages if \"FAILURE\" in msg)\n        self.assertGreater(failure_count, 0)\n        self.assertLess(len(messages), 30)  # Should be limited\n    \n    def test_edge_touching_boxes(self):\n        \"\"\"Test that boxes touching at edges don't count as intersecting\"\"\"\n        data = {\n            \"form_fields\": [\n                {\n                    \"description\": \"Name\",\n                    \"page_number\": 1,\n                    \"label_bounding_box\": [10, 10, 50, 30],\n                    \"entry_bounding_box\": [50, 10, 150, 30]  # Touches at x=50\n                }\n            ]\n        }\n        \n        stream = self.create_json_stream(data)\n        messages = get_bounding_box_messages(stream)\n        self.assertTrue(any(\"SUCCESS\" in msg for msg in messages))\n        self.assertFalse(any(\"FAILURE\" in msg for msg in messages))\n    \n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "document-skills/pdf/scripts/check_fillable_fields.py",
    "content": "import sys\nfrom pypdf import PdfReader\n\n\n# Script for Claude to run to determine whether a PDF has fillable form fields. See forms.md.\n\n\nreader = PdfReader(sys.argv[1])\nif (reader.get_fields()):\n    print(\"This PDF has fillable form fields\")\nelse:\n    print(\"This PDF does not have fillable form fields; you will need to visually determine where to enter data\")\n"
  },
  {
    "path": "document-skills/pdf/scripts/convert_pdf_to_images.py",
    "content": "import os\nimport sys\n\nfrom pdf2image import convert_from_path\n\n\n# Converts each page of a PDF to a PNG image.\n\n\ndef convert(pdf_path, output_dir, max_dim=1000):\n    images = convert_from_path(pdf_path, dpi=200)\n\n    for i, image in enumerate(images):\n        # Scale image if needed to keep width/height under `max_dim`\n        width, height = image.size\n        if width > max_dim or height > max_dim:\n            scale_factor = min(max_dim / width, max_dim / height)\n            new_width = int(width * scale_factor)\n            new_height = int(height * scale_factor)\n            image = image.resize((new_width, new_height))\n        \n        image_path = os.path.join(output_dir, f\"page_{i+1}.png\")\n        image.save(image_path)\n        print(f\"Saved page {i+1} as {image_path} (size: {image.size})\")\n\n    print(f\"Converted {len(images)} pages to PNG images\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 3:\n        print(\"Usage: convert_pdf_to_images.py [input pdf] [output directory]\")\n        sys.exit(1)\n    pdf_path = sys.argv[1]\n    output_directory = sys.argv[2]\n    convert(pdf_path, output_directory)\n"
  },
  {
    "path": "document-skills/pdf/scripts/create_validation_image.py",
    "content": "import json\nimport sys\n\nfrom PIL import Image, ImageDraw\n\n\n# Creates \"validation\" images with rectangles for the bounding box information that\n# Claude creates when determining where to add text annotations in PDFs. See forms.md.\n\n\ndef create_validation_image(page_number, fields_json_path, input_path, output_path):\n    # Input file should be in the `fields.json` format described in forms.md.\n    with open(fields_json_path, 'r') as f:\n        data = json.load(f)\n\n        img = Image.open(input_path)\n        draw = ImageDraw.Draw(img)\n        num_boxes = 0\n        \n        for field in data[\"form_fields\"]:\n            if field[\"page_number\"] == page_number:\n                entry_box = field['entry_bounding_box']\n                label_box = field['label_bounding_box']\n                # Draw red rectangle over entry bounding box and blue rectangle over the label.\n                draw.rectangle(entry_box, outline='red', width=2)\n                draw.rectangle(label_box, outline='blue', width=2)\n                num_boxes += 2\n        \n        img.save(output_path)\n        print(f\"Created validation image at {output_path} with {num_boxes} bounding boxes\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 5:\n        print(\"Usage: create_validation_image.py [page number] [fields.json file] [input image path] [output image path]\")\n        sys.exit(1)\n    page_number = int(sys.argv[1])\n    fields_json_path = sys.argv[2]\n    input_image_path = sys.argv[3]\n    output_image_path = sys.argv[4]\n    create_validation_image(page_number, fields_json_path, input_image_path, output_image_path)\n"
  },
  {
    "path": "document-skills/pdf/scripts/extract_form_field_info.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader\n\n\n# Extracts data for the fillable form fields in a PDF and outputs JSON that\n# Claude uses to fill the fields. See forms.md.\n\n\n# This matches the format used by PdfReader `get_fields` and `update_page_form_field_values` methods.\ndef get_full_annotation_field_id(annotation):\n    components = []\n    while annotation:\n        field_name = annotation.get('/T')\n        if field_name:\n            components.append(field_name)\n        annotation = annotation.get('/Parent')\n    return \".\".join(reversed(components)) if components else None\n\n\ndef make_field_dict(field, field_id):\n    field_dict = {\"field_id\": field_id}\n    ft = field.get('/FT')\n    if ft == \"/Tx\":\n        field_dict[\"type\"] = \"text\"\n    elif ft == \"/Btn\":\n        field_dict[\"type\"] = \"checkbox\"  # radio groups handled separately\n        states = field.get(\"/_States_\", [])\n        if len(states) == 2:\n            # \"/Off\" seems to always be the unchecked value, as suggested by\n            # https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf#page=448\n            # It can be either first or second in the \"/_States_\" list.\n            if \"/Off\" in states:\n                field_dict[\"checked_value\"] = states[0] if states[0] != \"/Off\" else states[1]\n                field_dict[\"unchecked_value\"] = \"/Off\"\n            else:\n                print(f\"Unexpected state values for checkbox `${field_id}`. Its checked and unchecked values may not be correct; if you're trying to check it, visually verify the results.\")\n                field_dict[\"checked_value\"] = states[0]\n                field_dict[\"unchecked_value\"] = states[1]\n    elif ft == \"/Ch\":\n        field_dict[\"type\"] = \"choice\"\n        states = field.get(\"/_States_\", [])\n        field_dict[\"choice_options\"] = [{\n            \"value\": state[0],\n            \"text\": state[1],\n        } for state in states]\n    else:\n        field_dict[\"type\"] = f\"unknown ({ft})\"\n    return field_dict\n\n\n# Returns a list of fillable PDF fields:\n# [\n#   {\n#     \"field_id\": \"name\",\n#     \"page\": 1,\n#     \"type\": (\"text\", \"checkbox\", \"radio_group\", or \"choice\")\n#     // Per-type additional fields described in forms.md\n#   },\n# ]\ndef get_field_info(reader: PdfReader):\n    fields = reader.get_fields()\n\n    field_info_by_id = {}\n    possible_radio_names = set()\n\n    for field_id, field in fields.items():\n        # Skip if this is a container field with children, except that it might be\n        # a parent group for radio button options.\n        if field.get(\"/Kids\"):\n            if field.get(\"/FT\") == \"/Btn\":\n                possible_radio_names.add(field_id)\n            continue\n        field_info_by_id[field_id] = make_field_dict(field, field_id)\n\n    # Bounding rects are stored in annotations in page objects.\n\n    # Radio button options have a separate annotation for each choice;\n    # all choices have the same field name.\n    # See https://westhealth.github.io/exploring-fillable-forms-with-pdfrw.html\n    radio_fields_by_id = {}\n\n    for page_index, page in enumerate(reader.pages):\n        annotations = page.get('/Annots', [])\n        for ann in annotations:\n            field_id = get_full_annotation_field_id(ann)\n            if field_id in field_info_by_id:\n                field_info_by_id[field_id][\"page\"] = page_index + 1\n                field_info_by_id[field_id][\"rect\"] = ann.get('/Rect')\n            elif field_id in possible_radio_names:\n                try:\n                    # ann['/AP']['/N'] should have two items. One of them is '/Off',\n                    # the other is the active value.\n                    on_values = [v for v in ann[\"/AP\"][\"/N\"] if v != \"/Off\"]\n                except KeyError:\n                    continue\n                if len(on_values) == 1:\n                    rect = ann.get(\"/Rect\")\n                    if field_id not in radio_fields_by_id:\n                        radio_fields_by_id[field_id] = {\n                            \"field_id\": field_id,\n                            \"type\": \"radio_group\",\n                            \"page\": page_index + 1,\n                            \"radio_options\": [],\n                        }\n                    # Note: at least on macOS 15.7, Preview.app doesn't show selected\n                    # radio buttons correctly. (It does if you remove the leading slash\n                    # from the value, but that causes them not to appear correctly in\n                    # Chrome/Firefox/Acrobat/etc).\n                    radio_fields_by_id[field_id][\"radio_options\"].append({\n                        \"value\": on_values[0],\n                        \"rect\": rect,\n                    })\n\n    # Some PDFs have form field definitions without corresponding annotations,\n    # so we can't tell where they are. Ignore these fields for now.\n    fields_with_location = []\n    for field_info in field_info_by_id.values():\n        if \"page\" in field_info:\n            fields_with_location.append(field_info)\n        else:\n            print(f\"Unable to determine location for field id: {field_info.get('field_id')}, ignoring\")\n\n    # Sort by page number, then Y position (flipped in PDF coordinate system), then X.\n    def sort_key(f):\n        if \"radio_options\" in f:\n            rect = f[\"radio_options\"][0][\"rect\"] or [0, 0, 0, 0]\n        else:\n            rect = f.get(\"rect\") or [0, 0, 0, 0]\n        adjusted_position = [-rect[1], rect[0]]\n        return [f.get(\"page\"), adjusted_position]\n    \n    sorted_fields = fields_with_location + list(radio_fields_by_id.values())\n    sorted_fields.sort(key=sort_key)\n\n    return sorted_fields\n\n\ndef write_field_info(pdf_path: str, json_output_path: str):\n    reader = PdfReader(pdf_path)\n    field_info = get_field_info(reader)\n    with open(json_output_path, \"w\") as f:\n        json.dump(field_info, f, indent=2)\n    print(f\"Wrote {len(field_info)} fields to {json_output_path}\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 3:\n        print(\"Usage: extract_form_field_info.py [input pdf] [output json]\")\n        sys.exit(1)\n    write_field_info(sys.argv[1], sys.argv[2])\n"
  },
  {
    "path": "document-skills/pdf/scripts/fill_fillable_fields.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader, PdfWriter\n\nfrom extract_form_field_info import get_field_info\n\n\n# Fills fillable form fields in a PDF. See forms.md.\n\n\ndef fill_pdf_fields(input_pdf_path: str, fields_json_path: str, output_pdf_path: str):\n    with open(fields_json_path) as f:\n        fields = json.load(f)\n    # Group by page number.\n    fields_by_page = {}\n    for field in fields:\n        if \"value\" in field:\n            field_id = field[\"field_id\"]\n            page = field[\"page\"]\n            if page not in fields_by_page:\n                fields_by_page[page] = {}\n            fields_by_page[page][field_id] = field[\"value\"]\n    \n    reader = PdfReader(input_pdf_path)\n\n    has_error = False\n    field_info = get_field_info(reader)\n    fields_by_ids = {f[\"field_id\"]: f for f in field_info}\n    for field in fields:\n        existing_field = fields_by_ids.get(field[\"field_id\"])\n        if not existing_field:\n            has_error = True\n            print(f\"ERROR: `{field['field_id']}` is not a valid field ID\")\n        elif field[\"page\"] != existing_field[\"page\"]:\n            has_error = True\n            print(f\"ERROR: Incorrect page number for `{field['field_id']}` (got {field['page']}, expected {existing_field['page']})\")\n        else:\n            if \"value\" in field:\n                err = validation_error_for_field_value(existing_field, field[\"value\"])\n                if err:\n                    print(err)\n                    has_error = True\n    if has_error:\n        sys.exit(1)\n\n    writer = PdfWriter(clone_from=reader)\n    for page, field_values in fields_by_page.items():\n        writer.update_page_form_field_values(writer.pages[page - 1], field_values, auto_regenerate=False)\n\n    # This seems to be necessary for many PDF viewers to format the form values correctly.\n    # It may cause the viewer to show a \"save changes\" dialog even if the user doesn't make any changes.\n    writer.set_need_appearances_writer(True)\n    \n    with open(output_pdf_path, \"wb\") as f:\n        writer.write(f)\n\n\ndef validation_error_for_field_value(field_info, field_value):\n    field_type = field_info[\"type\"]\n    field_id = field_info[\"field_id\"]\n    if field_type == \"checkbox\":\n        checked_val = field_info[\"checked_value\"]\n        unchecked_val = field_info[\"unchecked_value\"]\n        if field_value != checked_val and field_value != unchecked_val:\n            return f'ERROR: Invalid value \"{field_value}\" for checkbox field \"{field_id}\". The checked value is \"{checked_val}\" and the unchecked value is \"{unchecked_val}\"'\n    elif field_type == \"radio_group\":\n        option_values = [opt[\"value\"] for opt in field_info[\"radio_options\"]]\n        if field_value not in option_values:\n            return f'ERROR: Invalid value \"{field_value}\" for radio group field \"{field_id}\". Valid values are: {option_values}' \n    elif field_type == \"choice\":\n        choice_values = [opt[\"value\"] for opt in field_info[\"choice_options\"]]\n        if field_value not in choice_values:\n            return f'ERROR: Invalid value \"{field_value}\" for choice field \"{field_id}\". Valid values are: {choice_values}'\n    return None\n\n\n# pypdf (at least version 5.7.0) has a bug when setting the value for a selection list field.\n# In _writer.py around line 966:\n#\n# if field.get(FA.FT, \"/Tx\") == \"/Ch\" and field_flags & FA.FfBits.Combo == 0:\n#     txt = \"\\n\".join(annotation.get_inherited(FA.Opt, []))\n#\n# The problem is that for selection lists, `get_inherited` returns a list of two-element lists like\n# [[\"value1\", \"Text 1\"], [\"value2\", \"Text 2\"], ...]\n# This causes `join` to throw a TypeError because it expects an iterable of strings.\n# The horrible workaround is to patch `get_inherited` to return a list of the value strings.\n# We call the original method and adjust the return value only if the argument to `get_inherited`\n# is `FA.Opt` and if the return value is a list of two-element lists.\ndef monkeypatch_pydpf_method():\n    from pypdf.generic import DictionaryObject\n    from pypdf.constants import FieldDictionaryAttributes\n\n    original_get_inherited = DictionaryObject.get_inherited\n\n    def patched_get_inherited(self, key: str, default = None):\n        result = original_get_inherited(self, key, default)\n        if key == FieldDictionaryAttributes.Opt:\n            if isinstance(result, list) and all(isinstance(v, list) and len(v) == 2 for v in result):\n                result = [r[0] for r in result]\n        return result\n\n    DictionaryObject.get_inherited = patched_get_inherited\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 4:\n        print(\"Usage: fill_fillable_fields.py [input pdf] [field_values.json] [output pdf]\")\n        sys.exit(1)\n    monkeypatch_pydpf_method()\n    input_pdf = sys.argv[1]\n    fields_json = sys.argv[2]\n    output_pdf = sys.argv[3]\n    fill_pdf_fields(input_pdf, fields_json, output_pdf)\n"
  },
  {
    "path": "document-skills/pdf/scripts/fill_pdf_form_with_annotations.py",
    "content": "import json\nimport sys\n\nfrom pypdf import PdfReader, PdfWriter\nfrom pypdf.annotations import FreeText\n\n\n# Fills a PDF by adding text annotations defined in `fields.json`. See forms.md.\n\n\ndef transform_coordinates(bbox, image_width, image_height, pdf_width, pdf_height):\n    \"\"\"Transform bounding box from image coordinates to PDF coordinates\"\"\"\n    # Image coordinates: origin at top-left, y increases downward\n    # PDF coordinates: origin at bottom-left, y increases upward\n    x_scale = pdf_width / image_width\n    y_scale = pdf_height / image_height\n    \n    left = bbox[0] * x_scale\n    right = bbox[2] * x_scale\n    \n    # Flip Y coordinates for PDF\n    top = pdf_height - (bbox[1] * y_scale)\n    bottom = pdf_height - (bbox[3] * y_scale)\n    \n    return left, bottom, right, top\n\n\ndef fill_pdf_form(input_pdf_path, fields_json_path, output_pdf_path):\n    \"\"\"Fill the PDF form with data from fields.json\"\"\"\n    \n    # `fields.json` format described in forms.md.\n    with open(fields_json_path, \"r\") as f:\n        fields_data = json.load(f)\n    \n    # Open the PDF\n    reader = PdfReader(input_pdf_path)\n    writer = PdfWriter()\n    \n    # Copy all pages to writer\n    writer.append(reader)\n    \n    # Get PDF dimensions for each page\n    pdf_dimensions = {}\n    for i, page in enumerate(reader.pages):\n        mediabox = page.mediabox\n        pdf_dimensions[i + 1] = [mediabox.width, mediabox.height]\n    \n    # Process each form field\n    annotations = []\n    for field in fields_data[\"form_fields\"]:\n        page_num = field[\"page_number\"]\n        \n        # Get page dimensions and transform coordinates.\n        page_info = next(p for p in fields_data[\"pages\"] if p[\"page_number\"] == page_num)\n        image_width = page_info[\"image_width\"]\n        image_height = page_info[\"image_height\"]\n        pdf_width, pdf_height = pdf_dimensions[page_num]\n        \n        transformed_entry_box = transform_coordinates(\n            field[\"entry_bounding_box\"],\n            image_width, image_height,\n            pdf_width, pdf_height\n        )\n        \n        # Skip empty fields\n        if \"entry_text\" not in field or \"text\" not in field[\"entry_text\"]:\n            continue\n        entry_text = field[\"entry_text\"]\n        text = entry_text[\"text\"]\n        if not text:\n            continue\n        \n        font_name = entry_text.get(\"font\", \"Arial\")\n        font_size = str(entry_text.get(\"font_size\", 14)) + \"pt\"\n        font_color = entry_text.get(\"font_color\", \"000000\")\n\n        # Font size/color seems to not work reliably across viewers:\n        # https://github.com/py-pdf/pypdf/issues/2084\n        annotation = FreeText(\n            text=text,\n            rect=transformed_entry_box,\n            font=font_name,\n            font_size=font_size,\n            font_color=font_color,\n            border_color=None,\n            background_color=None,\n        )\n        annotations.append(annotation)\n        # page_number is 0-based for pypdf\n        writer.add_annotation(page_number=page_num - 1, annotation=annotation)\n        \n    # Save the filled PDF\n    with open(output_pdf_path, \"wb\") as output:\n        writer.write(output)\n    \n    print(f\"Successfully filled PDF form and saved to {output_pdf_path}\")\n    print(f\"Added {len(annotations)} text annotations\")\n\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 4:\n        print(\"Usage: fill_pdf_form_with_annotations.py [input pdf] [fields.json] [output pdf]\")\n        sys.exit(1)\n    input_pdf = sys.argv[1]\n    fields_json = sys.argv[2]\n    output_pdf = sys.argv[3]\n    \n    fill_pdf_form(input_pdf, fields_json, output_pdf)"
  },
  {
    "path": "document-skills/pptx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "document-skills/pptx/SKILL.md",
    "content": "---\nname: pptx\ndescription: \"Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# PPTX creation, editing, and analysis\n\n## Overview\n\nA user may ask you to create, edit, or analyze the contents of a .pptx file. A .pptx file is essentially a ZIP archive containing XML files and other resources that you can read or edit. You have different tools and workflows available for different tasks.\n\n## Reading and analyzing content\n\n### Text extraction\nIf you just need to read the text contents of a presentation, you should convert the document to markdown:\n\n```bash\n# Convert document to markdown\npython -m markitdown path-to-file.pptx\n```\n\n### Raw XML access\nYou need raw XML access for: comments, speaker notes, slide layouts, animations, design elements, and complex formatting. For any of these features, you'll need to unpack a presentation and read its raw XML contents.\n\n#### Unpacking a file\n`python ooxml/scripts/unpack.py <office_file> <output_dir>`\n\n**Note**: The unpack.py script is located at `skills/pptx/ooxml/scripts/unpack.py` relative to the project root. If the script doesn't exist at this path, use `find . -name \"unpack.py\"` to locate it.\n\n#### Key file structures\n* `ppt/presentation.xml` - Main presentation metadata and slide references\n* `ppt/slides/slide{N}.xml` - Individual slide contents (slide1.xml, slide2.xml, etc.)\n* `ppt/notesSlides/notesSlide{N}.xml` - Speaker notes for each slide\n* `ppt/comments/modernComment_*.xml` - Comments for specific slides\n* `ppt/slideLayouts/` - Layout templates for slides\n* `ppt/slideMasters/` - Master slide templates\n* `ppt/theme/` - Theme and styling information\n* `ppt/media/` - Images and other media files\n\n#### Typography and color extraction\n**When given an example design to emulate**: Always analyze the presentation's typography and colors first using the methods below:\n1. **Read theme file**: Check `ppt/theme/theme1.xml` for colors (`<a:clrScheme>`) and fonts (`<a:fontScheme>`)\n2. **Sample slide content**: Examine `ppt/slides/slide1.xml` for actual font usage (`<a:rPr>`) and colors\n3. **Search for patterns**: Use grep to find color (`<a:solidFill>`, `<a:srgbClr>`) and font references across all XML files\n\n## Creating a new PowerPoint presentation **without a template**\n\nWhen creating a new PowerPoint presentation from scratch, use the **html2pptx** workflow to convert HTML slides to PowerPoint with accurate positioning.\n\n### Design Principles\n\n**CRITICAL**: Before creating any presentation, analyze the content and choose appropriate design elements:\n1. **Consider the subject matter**: What is this presentation about? What tone, industry, or mood does it suggest?\n2. **Check for branding**: If the user mentions a company/organization, consider their brand colors and identity\n3. **Match palette to content**: Select colors that reflect the subject\n4. **State your approach**: Explain your design choices before writing code\n\n**Requirements**:\n- ✅ State your content-informed design approach BEFORE writing code\n- ✅ Use web-safe fonts only: Arial, Helvetica, Times New Roman, Georgia, Courier New, Verdana, Tahoma, Trebuchet MS, Impact\n- ✅ Create clear visual hierarchy through size, weight, and color\n- ✅ Ensure readability: strong contrast, appropriately sized text, clean alignment\n- ✅ Be consistent: repeat patterns, spacing, and visual language across slides\n\n#### Color Palette Selection\n\n**Choosing colors creatively**:\n- **Think beyond defaults**: What colors genuinely match this specific topic? Avoid autopilot choices.\n- **Consider multiple angles**: Topic, industry, mood, energy level, target audience, brand identity (if mentioned)\n- **Be adventurous**: Try unexpected combinations - a healthcare presentation doesn't have to be green, finance doesn't have to be navy\n- **Build your palette**: Pick 3-5 colors that work together (dominant colors + supporting tones + accent)\n- **Ensure contrast**: Text must be clearly readable on backgrounds\n\n**Example color palettes** (use these to spark creativity - choose one, adapt it, or create your own):\n\n1. **Classic Blue**: Deep navy (#1C2833), slate gray (#2E4053), silver (#AAB7B8), off-white (#F4F6F6)\n2. **Teal & Coral**: Teal (#5EA8A7), deep teal (#277884), coral (#FE4447), white (#FFFFFF)\n3. **Bold Red**: Red (#C0392B), bright red (#E74C3C), orange (#F39C12), yellow (#F1C40F), green (#2ECC71)\n4. **Warm Blush**: Mauve (#A49393), blush (#EED6D3), rose (#E8B4B8), cream (#FAF7F2)\n5. **Burgundy Luxury**: Burgundy (#5D1D2E), crimson (#951233), rust (#C15937), gold (#997929)\n6. **Deep Purple & Emerald**: Purple (#B165FB), dark blue (#181B24), emerald (#40695B), white (#FFFFFF)\n7. **Cream & Forest Green**: Cream (#FFE1C7), forest green (#40695B), white (#FCFCFC)\n8. **Pink & Purple**: Pink (#F8275B), coral (#FF574A), rose (#FF737D), purple (#3D2F68)\n9. **Lime & Plum**: Lime (#C5DE82), plum (#7C3A5F), coral (#FD8C6E), blue-gray (#98ACB5)\n10. **Black & Gold**: Gold (#BF9A4A), black (#000000), cream (#F4F6F6)\n11. **Sage & Terracotta**: Sage (#87A96B), terracotta (#E07A5F), cream (#F4F1DE), charcoal (#2C2C2C)\n12. **Charcoal & Red**: Charcoal (#292929), red (#E33737), light gray (#CCCBCB)\n13. **Vibrant Orange**: Orange (#F96D00), light gray (#F2F2F2), charcoal (#222831)\n14. **Forest Green**: Black (#191A19), green (#4E9F3D), dark green (#1E5128), white (#FFFFFF)\n15. **Retro Rainbow**: Purple (#722880), pink (#D72D51), orange (#EB5C18), amber (#F08800), gold (#DEB600)\n16. **Vintage Earthy**: Mustard (#E3B448), sage (#CBD18F), forest green (#3A6B35), cream (#F4F1DE)\n17. **Coastal Rose**: Old rose (#AD7670), beaver (#B49886), eggshell (#F3ECDC), ash gray (#BFD5BE)\n18. **Orange & Turquoise**: Light orange (#FC993E), grayish turquoise (#667C6F), white (#FCFCFC)\n\n#### Visual Details Options\n\n**Geometric Patterns**:\n- Diagonal section dividers instead of horizontal\n- Asymmetric column widths (30/70, 40/60, 25/75)\n- Rotated text headers at 90° or 270°\n- Circular/hexagonal frames for images\n- Triangular accent shapes in corners\n- Overlapping shapes for depth\n\n**Border & Frame Treatments**:\n- Thick single-color borders (10-20pt) on one side only\n- Double-line borders with contrasting colors\n- Corner brackets instead of full frames\n- L-shaped borders (top+left or bottom+right)\n- Underline accents beneath headers (3-5pt thick)\n\n**Typography Treatments**:\n- Extreme size contrast (72pt headlines vs 11pt body)\n- All-caps headers with wide letter spacing\n- Numbered sections in oversized display type\n- Monospace (Courier New) for data/stats/technical content\n- Condensed fonts (Arial Narrow) for dense information\n- Outlined text for emphasis\n\n**Chart & Data Styling**:\n- Monochrome charts with single accent color for key data\n- Horizontal bar charts instead of vertical\n- Dot plots instead of bar charts\n- Minimal gridlines or none at all\n- Data labels directly on elements (no legends)\n- Oversized numbers for key metrics\n\n**Layout Innovations**:\n- Full-bleed images with text overlays\n- Sidebar column (20-30% width) for navigation/context\n- Modular grid systems (3×3, 4×4 blocks)\n- Z-pattern or F-pattern content flow\n- Floating text boxes over colored shapes\n- Magazine-style multi-column layouts\n\n**Background Treatments**:\n- Solid color blocks occupying 40-60% of slide\n- Gradient fills (vertical or diagonal only)\n- Split backgrounds (two colors, diagonal or vertical)\n- Edge-to-edge color bands\n- Negative space as a design element\n\n### Layout Tips\n**When creating slides with charts or tables:**\n- **Two-column layout (PREFERRED)**: Use a header spanning the full width, then two columns below - text/bullets in one column and the featured content in the other. This provides better balance and makes charts/tables more readable. Use flexbox with unequal column widths (e.g., 40%/60% split) to optimize space for each content type.\n- **Full-slide layout**: Let the featured content (chart/table) take up the entire slide for maximum impact and readability\n- **NEVER vertically stack**: Do not place charts/tables below text in a single column - this causes poor readability and layout issues\n\n### Workflow\n1. **MANDATORY - READ ENTIRE FILE**: Read [`html2pptx.md`](html2pptx.md) completely from start to finish. **NEVER set any range limits when reading this file.** Read the full file content for detailed syntax, critical formatting rules, and best practices before proceeding with presentation creation.\n2. Create an HTML file for each slide with proper dimensions (e.g., 720pt × 405pt for 16:9)\n   - Use `<p>`, `<h1>`-`<h6>`, `<ul>`, `<ol>` for all text content\n   - Use `class=\"placeholder\"` for areas where charts/tables will be added (render with gray background for visibility)\n   - **CRITICAL**: Rasterize gradients and icons as PNG images FIRST using Sharp, then reference in HTML\n   - **LAYOUT**: For slides with charts/tables/images, use either full-slide layout or two-column layout for better readability\n3. Create and run a JavaScript file using the [`html2pptx.js`](scripts/html2pptx.js) library to convert HTML slides to PowerPoint and save the presentation\n   - Use the `html2pptx()` function to process each HTML file\n   - Add charts and tables to placeholder areas using PptxGenJS API\n   - Save the presentation using `pptx.writeFile()`\n4. **Visual validation**: Generate thumbnails and inspect for layout issues\n   - Create thumbnail grid: `python scripts/thumbnail.py output.pptx workspace/thumbnails --cols 4`\n   - Read and carefully examine the thumbnail image for:\n     - **Text cutoff**: Text being cut off by header bars, shapes, or slide edges\n     - **Text overlap**: Text overlapping with other text or shapes\n     - **Positioning issues**: Content too close to slide boundaries or other elements\n     - **Contrast issues**: Insufficient contrast between text and backgrounds\n   - If issues found, adjust HTML margins/spacing/colors and regenerate the presentation\n   - Repeat until all slides are visually correct\n\n## Editing an existing PowerPoint presentation\n\nWhen edit slides in an existing PowerPoint presentation, you need to work with the raw Office Open XML (OOXML) format. This involves unpacking the .pptx file, editing the XML content, and repacking it.\n\n### Workflow\n1. **MANDATORY - READ ENTIRE FILE**: Read [`ooxml.md`](ooxml.md) (~500 lines) completely from start to finish.  **NEVER set any range limits when reading this file.**  Read the full file content for detailed guidance on OOXML structure and editing workflows before any presentation editing.\n2. Unpack the presentation: `python ooxml/scripts/unpack.py <office_file> <output_dir>`\n3. Edit the XML files (primarily `ppt/slides/slide{N}.xml` and related files)\n4. **CRITICAL**: Validate immediately after each edit and fix any validation errors before proceeding: `python ooxml/scripts/validate.py <dir> --original <file>`\n5. Pack the final presentation: `python ooxml/scripts/pack.py <input_directory> <office_file>`\n\n## Creating a new PowerPoint presentation **using a template**\n\nWhen you need to create a presentation that follows an existing template's design, you'll need to duplicate and re-arrange template slides before then replacing placeholder context.\n\n### Workflow\n1. **Extract template text AND create visual thumbnail grid**:\n   * Extract text: `python -m markitdown template.pptx > template-content.md`\n   * Read `template-content.md`: Read the entire file to understand the contents of the template presentation. **NEVER set any range limits when reading this file.**\n   * Create thumbnail grids: `python scripts/thumbnail.py template.pptx`\n   * See [Creating Thumbnail Grids](#creating-thumbnail-grids) section for more details\n\n2. **Analyze template and save inventory to a file**:\n   * **Visual Analysis**: Review thumbnail grid(s) to understand slide layouts, design patterns, and visual structure\n   * Create and save a template inventory file at `template-inventory.md` containing:\n     ```markdown\n     # Template Inventory Analysis\n     **Total Slides: [count]**\n     **IMPORTANT: Slides are 0-indexed (first slide = 0, last slide = count-1)**\n\n     ## [Category Name]\n     - Slide 0: [Layout code if available] - Description/purpose\n     - Slide 1: [Layout code] - Description/purpose\n     - Slide 2: [Layout code] - Description/purpose\n     [... EVERY slide must be listed individually with its index ...]\n     ```\n   * **Using the thumbnail grid**: Reference the visual thumbnails to identify:\n     - Layout patterns (title slides, content layouts, section dividers)\n     - Image placeholder locations and counts\n     - Design consistency across slide groups\n     - Visual hierarchy and structure\n   * This inventory file is REQUIRED for selecting appropriate templates in the next step\n\n3. **Create presentation outline based on template inventory**:\n   * Review available templates from step 2.\n   * Choose an intro or title template for the first slide. This should be one of the first templates.\n   * Choose safe, text-based layouts for the other slides.\n   * **CRITICAL: Match layout structure to actual content**:\n     - Single-column layouts: Use for unified narrative or single topic\n     - Two-column layouts: Use ONLY when you have exactly 2 distinct items/concepts\n     - Three-column layouts: Use ONLY when you have exactly 3 distinct items/concepts\n     - Image + text layouts: Use ONLY when you have actual images to insert\n     - Quote layouts: Use ONLY for actual quotes from people (with attribution), never for emphasis\n     - Never use layouts with more placeholders than you have content\n     - If you have 2 items, don't force them into a 3-column layout\n     - If you have 4+ items, consider breaking into multiple slides or using a list format\n   * Count your actual content pieces BEFORE selecting the layout\n   * Verify each placeholder in the chosen layout will be filled with meaningful content\n   * Select one option representing the **best** layout for each content section.\n   * Save `outline.md` with content AND template mapping that leverages available designs\n   * Example template mapping:\n      ```\n      # Template slides to use (0-based indexing)\n      # WARNING: Verify indices are within range! Template with 73 slides has indices 0-72\n      # Mapping: slide numbers from outline -> template slide indices\n      template_mapping = [\n          0,   # Use slide 0 (Title/Cover)\n          34,  # Use slide 34 (B1: Title and body)\n          34,  # Use slide 34 again (duplicate for second B1)\n          50,  # Use slide 50 (E1: Quote)\n          54,  # Use slide 54 (F2: Closing + Text)\n      ]\n      ```\n\n4. **Duplicate, reorder, and delete slides using `rearrange.py`**:\n   * Use the `scripts/rearrange.py` script to create a new presentation with slides in the desired order:\n     ```bash\n     python scripts/rearrange.py template.pptx working.pptx 0,34,34,50,52\n     ```\n   * The script handles duplicating repeated slides, deleting unused slides, and reordering automatically\n   * Slide indices are 0-based (first slide is 0, second is 1, etc.)\n   * The same slide index can appear multiple times to duplicate that slide\n\n5. **Extract ALL text using the `inventory.py` script**:\n   * **Run inventory extraction**:\n     ```bash\n     python scripts/inventory.py working.pptx text-inventory.json\n     ```\n   * **Read text-inventory.json**: Read the entire text-inventory.json file to understand all shapes and their properties. **NEVER set any range limits when reading this file.**\n\n   * The inventory JSON structure:\n      ```json\n        {\n          \"slide-0\": {\n            \"shape-0\": {\n              \"placeholder_type\": \"TITLE\",  // or null for non-placeholders\n              \"left\": 1.5,                  // position in inches\n              \"top\": 2.0,\n              \"width\": 7.5,\n              \"height\": 1.2,\n              \"paragraphs\": [\n                {\n                  \"text\": \"Paragraph text\",\n                  // Optional properties (only included when non-default):\n                  \"bullet\": true,           // explicit bullet detected\n                  \"level\": 0,               // only included when bullet is true\n                  \"alignment\": \"CENTER\",    // CENTER, RIGHT (not LEFT)\n                  \"space_before\": 10.0,     // space before paragraph in points\n                  \"space_after\": 6.0,       // space after paragraph in points\n                  \"line_spacing\": 22.4,     // line spacing in points\n                  \"font_name\": \"Arial\",     // from first run\n                  \"font_size\": 14.0,        // in points\n                  \"bold\": true,\n                  \"italic\": false,\n                  \"underline\": false,\n                  \"color\": \"FF0000\"         // RGB color\n                }\n              ]\n            }\n          }\n        }\n      ```\n\n   * Key features:\n     - **Slides**: Named as \"slide-0\", \"slide-1\", etc.\n     - **Shapes**: Ordered by visual position (top-to-bottom, left-to-right) as \"shape-0\", \"shape-1\", etc.\n     - **Placeholder types**: TITLE, CENTER_TITLE, SUBTITLE, BODY, OBJECT, or null\n     - **Default font size**: `default_font_size` in points extracted from layout placeholders (when available)\n     - **Slide numbers are filtered**: Shapes with SLIDE_NUMBER placeholder type are automatically excluded from inventory\n     - **Bullets**: When `bullet: true`, `level` is always included (even if 0)\n     - **Spacing**: `space_before`, `space_after`, and `line_spacing` in points (only included when set)\n     - **Colors**: `color` for RGB (e.g., \"FF0000\"), `theme_color` for theme colors (e.g., \"DARK_1\")\n     - **Properties**: Only non-default values are included in the output\n\n6. **Generate replacement text and save the data to a JSON file**\n   Based on the text inventory from the previous step:\n   - **CRITICAL**: First verify which shapes exist in the inventory - only reference shapes that are actually present\n   - **VALIDATION**: The replace.py script will validate that all shapes in your replacement JSON exist in the inventory\n     - If you reference a non-existent shape, you'll get an error showing available shapes\n     - If you reference a non-existent slide, you'll get an error indicating the slide doesn't exist\n     - All validation errors are shown at once before the script exits\n   - **IMPORTANT**: The replace.py script uses inventory.py internally to identify ALL text shapes\n   - **AUTOMATIC CLEARING**: ALL text shapes from the inventory will be cleared unless you provide \"paragraphs\" for them\n   - Add a \"paragraphs\" field to shapes that need content (not \"replacement_paragraphs\")\n   - Shapes without \"paragraphs\" in the replacement JSON will have their text cleared automatically\n   - Paragraphs with bullets will be automatically left aligned. Don't set the `alignment` property on when `\"bullet\": true`\n   - Generate appropriate replacement content for placeholder text\n   - Use shape size to determine appropriate content length\n   - **CRITICAL**: Include paragraph properties from the original inventory - don't just provide text\n   - **IMPORTANT**: When bullet: true, do NOT include bullet symbols (•, -, *) in text - they're added automatically\n   - **ESSENTIAL FORMATTING RULES**:\n     - Headers/titles should typically have `\"bold\": true`\n     - List items should have `\"bullet\": true, \"level\": 0` (level is required when bullet is true)\n     - Preserve any alignment properties (e.g., `\"alignment\": \"CENTER\"` for centered text)\n     - Include font properties when different from default (e.g., `\"font_size\": 14.0`, `\"font_name\": \"Lora\"`)\n     - Colors: Use `\"color\": \"FF0000\"` for RGB or `\"theme_color\": \"DARK_1\"` for theme colors\n     - The replacement script expects **properly formatted paragraphs**, not just text strings\n     - **Overlapping shapes**: Prefer shapes with larger default_font_size or more appropriate placeholder_type\n   - Save the updated inventory with replacements to `replacement-text.json`\n   - **WARNING**: Different template layouts have different shape counts - always check the actual inventory before creating replacements\n\n   Example paragraphs field showing proper formatting:\n   ```json\n   \"paragraphs\": [\n     {\n       \"text\": \"New presentation title text\",\n       \"alignment\": \"CENTER\",\n       \"bold\": true\n     },\n     {\n       \"text\": \"Section Header\",\n       \"bold\": true\n     },\n     {\n       \"text\": \"First bullet point without bullet symbol\",\n       \"bullet\": true,\n       \"level\": 0\n     },\n     {\n       \"text\": \"Red colored text\",\n       \"color\": \"FF0000\"\n     },\n     {\n       \"text\": \"Theme colored text\",\n       \"theme_color\": \"DARK_1\"\n     },\n     {\n       \"text\": \"Regular paragraph text without special formatting\"\n     }\n   ]\n   ```\n\n   **Shapes not listed in the replacement JSON are automatically cleared**:\n   ```json\n   {\n     \"slide-0\": {\n       \"shape-0\": {\n         \"paragraphs\": [...] // This shape gets new text\n       }\n       // shape-1 and shape-2 from inventory will be cleared automatically\n     }\n   }\n   ```\n\n   **Common formatting patterns for presentations**:\n   - Title slides: Bold text, sometimes centered\n   - Section headers within slides: Bold text\n   - Bullet lists: Each item needs `\"bullet\": true, \"level\": 0`\n   - Body text: Usually no special properties needed\n   - Quotes: May have special alignment or font properties\n\n7. **Apply replacements using the `replace.py` script**\n   ```bash\n   python scripts/replace.py working.pptx replacement-text.json output.pptx\n   ```\n\n   The script will:\n   - First extract the inventory of ALL text shapes using functions from inventory.py\n   - Validate that all shapes in the replacement JSON exist in the inventory\n   - Clear text from ALL shapes identified in the inventory\n   - Apply new text only to shapes with \"paragraphs\" defined in the replacement JSON\n   - Preserve formatting by applying paragraph properties from the JSON\n   - Handle bullets, alignment, font properties, and colors automatically\n   - Save the updated presentation\n\n   Example validation errors:\n   ```\n   ERROR: Invalid shapes in replacement JSON:\n     - Shape 'shape-99' not found on 'slide-0'. Available shapes: shape-0, shape-1, shape-4\n     - Slide 'slide-999' not found in inventory\n   ```\n\n   ```\n   ERROR: Replacement text made overflow worse in these shapes:\n     - slide-0/shape-2: overflow worsened by 1.25\" (was 0.00\", now 1.25\")\n   ```\n\n## Creating Thumbnail Grids\n\nTo create visual thumbnail grids of PowerPoint slides for quick analysis and reference:\n\n```bash\npython scripts/thumbnail.py template.pptx [output_prefix]\n```\n\n**Features**:\n- Creates: `thumbnails.jpg` (or `thumbnails-1.jpg`, `thumbnails-2.jpg`, etc. for large decks)\n- Default: 5 columns, max 30 slides per grid (5×6)\n- Custom prefix: `python scripts/thumbnail.py template.pptx my-grid`\n  - Note: The output prefix should include the path if you want output in a specific directory (e.g., `workspace/my-grid`)\n- Adjust columns: `--cols 4` (range: 3-6, affects slides per grid)\n- Grid limits: 3 cols = 12 slides/grid, 4 cols = 20, 5 cols = 30, 6 cols = 42\n- Slides are zero-indexed (Slide 0, Slide 1, etc.)\n\n**Use cases**:\n- Template analysis: Quickly understand slide layouts and design patterns\n- Content review: Visual overview of entire presentation\n- Navigation reference: Find specific slides by their visual appearance\n- Quality check: Verify all slides are properly formatted\n\n**Examples**:\n```bash\n# Basic usage\npython scripts/thumbnail.py presentation.pptx\n\n# Combine options: custom name, columns\npython scripts/thumbnail.py template.pptx analysis --cols 4\n```\n\n## Converting Slides to Images\n\nTo visually analyze PowerPoint slides, convert them to images using a two-step process:\n\n1. **Convert PPTX to PDF**:\n   ```bash\n   soffice --headless --convert-to pdf template.pptx\n   ```\n\n2. **Convert PDF pages to JPEG images**:\n   ```bash\n   pdftoppm -jpeg -r 150 template.pdf slide\n   ```\n   This creates files like `slide-1.jpg`, `slide-2.jpg`, etc.\n\nOptions:\n- `-r 150`: Sets resolution to 150 DPI (adjust for quality/size balance)\n- `-jpeg`: Output JPEG format (use `-png` for PNG if preferred)\n- `-f N`: First page to convert (e.g., `-f 2` starts from page 2)\n- `-l N`: Last page to convert (e.g., `-l 5` stops at page 5)\n- `slide`: Prefix for output files\n\nExample for specific range:\n```bash\npdftoppm -jpeg -r 150 -f 2 -l 5 template.pdf slide  # Converts only pages 2-5\n```\n\n## Code Style Guidelines\n**IMPORTANT**: When generating code for PPTX operations:\n- Write concise code\n- Avoid verbose variable names and redundant operations\n- Avoid unnecessary print statements\n\n## Dependencies\n\nRequired dependencies (should already be installed):\n\n- **markitdown**: `pip install \"markitdown[pptx]\"` (for text extraction from presentations)\n- **pptxgenjs**: `npm install -g pptxgenjs` (for creating presentations via html2pptx)\n- **playwright**: `npm install -g playwright` (for HTML rendering in html2pptx)\n- **react-icons**: `npm install -g react-icons react react-dom` (for icons)\n- **sharp**: `npm install -g sharp` (for SVG rasterization and image processing)\n- **LibreOffice**: `sudo apt-get install libreoffice` (for PDF conversion)\n- **Poppler**: `sudo apt-get install poppler-utils` (for pdftoppm to convert PDF to images)\n- **defusedxml**: `pip install defusedxml` (for secure XML parsing)"
  },
  {
    "path": "document-skills/pptx/html2pptx.md",
    "content": "# HTML to PowerPoint Guide\n\nConvert HTML slides to PowerPoint presentations with accurate positioning using the `html2pptx.js` library.\n\n## Table of Contents\n\n1. [Creating HTML Slides](#creating-html-slides)\n2. [Using the html2pptx Library](#using-the-html2pptx-library)\n3. [Using PptxGenJS](#using-pptxgenjs)\n\n---\n\n## Creating HTML Slides\n\nEvery HTML slide must include proper body dimensions:\n\n### Layout Dimensions\n\n- **16:9** (default): `width: 720pt; height: 405pt`\n- **4:3**: `width: 720pt; height: 540pt`\n- **16:10**: `width: 720pt; height: 450pt`\n\n### Supported Elements\n\n- `<p>`, `<h1>`-`<h6>` - Text with styling\n- `<ul>`, `<ol>` - Lists (never use manual bullets •, -, *)\n- `<b>`, `<strong>` - Bold text (inline formatting)\n- `<i>`, `<em>` - Italic text (inline formatting)\n- `<u>` - Underlined text (inline formatting)\n- `<span>` - Inline formatting with CSS styles (bold, italic, underline, color)\n- `<br>` - Line breaks\n- `<div>` with bg/border - Becomes shape\n- `<img>` - Images\n- `class=\"placeholder\"` - Reserved space for charts (returns `{ id, x, y, w, h }`)\n\n### Critical Text Rules\n\n**ALL text MUST be inside `<p>`, `<h1>`-`<h6>`, `<ul>`, or `<ol>` tags:**\n- ✅ Correct: `<div><p>Text here</p></div>`\n- ❌ Wrong: `<div>Text here</div>` - **Text will NOT appear in PowerPoint**\n- ❌ Wrong: `<span>Text</span>` - **Text will NOT appear in PowerPoint**\n- Text in `<div>` or `<span>` without a text tag will be silently ignored\n\n**NEVER use manual bullet symbols (•, -, *, etc.)** - Use `<ul>` or `<ol>` lists instead\n\n**ONLY use web-safe fonts that are universally available:**\n- ✅ Web-safe fonts: `Arial`, `Helvetica`, `Times New Roman`, `Georgia`, `Courier New`, `Verdana`, `Tahoma`, `Trebuchet MS`, `Impact`, `Comic Sans MS`\n- ❌ Wrong: `'Segoe UI'`, `'SF Pro'`, `'Roboto'`, custom fonts - **Might cause rendering issues**\n\n### Styling\n\n- Use `display: flex` on body to prevent margin collapse from breaking overflow validation\n- Use `margin` for spacing (padding included in size)\n- Inline formatting: Use `<b>`, `<i>`, `<u>` tags OR `<span>` with CSS styles\n  - `<span>` supports: `font-weight: bold`, `font-style: italic`, `text-decoration: underline`, `color: #rrggbb`\n  - `<span>` does NOT support: `margin`, `padding` (not supported in PowerPoint text runs)\n  - Example: `<span style=\"font-weight: bold; color: #667eea;\">Bold blue text</span>`\n- Flexbox works - positions calculated from rendered layout\n- Use hex colors with `#` prefix in CSS\n- **Text alignment**: Use CSS `text-align` (`center`, `right`, etc.) when needed as a hint to PptxGenJS for text formatting if text lengths are slightly off\n\n### Shape Styling (DIV elements only)\n\n**IMPORTANT: Backgrounds, borders, and shadows only work on `<div>` elements, NOT on text elements (`<p>`, `<h1>`-`<h6>`, `<ul>`, `<ol>`)**\n\n- **Backgrounds**: CSS `background` or `background-color` on `<div>` elements only\n  - Example: `<div style=\"background: #f0f0f0;\">` - Creates a shape with background\n- **Borders**: CSS `border` on `<div>` elements converts to PowerPoint shape borders\n  - Supports uniform borders: `border: 2px solid #333333`\n  - Supports partial borders: `border-left`, `border-right`, `border-top`, `border-bottom` (rendered as line shapes)\n  - Example: `<div style=\"border-left: 8pt solid #E76F51;\">`\n- **Border radius**: CSS `border-radius` on `<div>` elements for rounded corners\n  - `border-radius: 50%` or higher creates circular shape\n  - Percentages <50% calculated relative to shape's smaller dimension\n  - Supports px and pt units (e.g., `border-radius: 8pt;`, `border-radius: 12px;`)\n  - Example: `<div style=\"border-radius: 25%;\">` on 100x200px box = 25% of 100px = 25px radius\n- **Box shadows**: CSS `box-shadow` on `<div>` elements converts to PowerPoint shadows\n  - Supports outer shadows only (inset shadows are ignored to prevent corruption)\n  - Example: `<div style=\"box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);\">`\n  - Note: Inset/inner shadows are not supported by PowerPoint and will be skipped\n\n### Icons & Gradients\n\n- **CRITICAL: Never use CSS gradients (`linear-gradient`, `radial-gradient`)** - They don't convert to PowerPoint\n- **ALWAYS create gradient/icon PNGs FIRST using Sharp, then reference in HTML**\n- For gradients: Rasterize SVG to PNG background images\n- For icons: Rasterize react-icons SVG to PNG images\n- All visual effects must be pre-rendered as raster images before HTML rendering\n\n**Rasterizing Icons with Sharp:**\n\n```javascript\nconst React = require('react');\nconst ReactDOMServer = require('react-dom/server');\nconst sharp = require('sharp');\nconst { FaHome } = require('react-icons/fa');\n\nasync function rasterizeIconPng(IconComponent, color, size = \"256\", filename) {\n  const svgString = ReactDOMServer.renderToStaticMarkup(\n    React.createElement(IconComponent, { color: `#${color}`, size: size })\n  );\n\n  // Convert SVG to PNG using Sharp\n  await sharp(Buffer.from(svgString))\n    .png()\n    .toFile(filename);\n\n  return filename;\n}\n\n// Usage: Rasterize icon before using in HTML\nconst iconPath = await rasterizeIconPng(FaHome, \"4472c4\", \"256\", \"home-icon.png\");\n// Then reference in HTML: <img src=\"home-icon.png\" style=\"width: 40pt; height: 40pt;\">\n```\n\n**Rasterizing Gradients with Sharp:**\n\n```javascript\nconst sharp = require('sharp');\n\nasync function createGradientBackground(filename) {\n  const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1000\" height=\"562.5\">\n    <defs>\n      <linearGradient id=\"g\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n        <stop offset=\"0%\" style=\"stop-color:#COLOR1\"/>\n        <stop offset=\"100%\" style=\"stop-color:#COLOR2\"/>\n      </linearGradient>\n    </defs>\n    <rect width=\"100%\" height=\"100%\" fill=\"url(#g)\"/>\n  </svg>`;\n\n  await sharp(Buffer.from(svg))\n    .png()\n    .toFile(filename);\n\n  return filename;\n}\n\n// Usage: Create gradient background before HTML\nconst bgPath = await createGradientBackground(\"gradient-bg.png\");\n// Then in HTML: <body style=\"background-image: url('gradient-bg.png');\">\n```\n\n### Example\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n<style>\nhtml { background: #ffffff; }\nbody {\n  width: 720pt; height: 405pt; margin: 0; padding: 0;\n  background: #f5f5f5; font-family: Arial, sans-serif;\n  display: flex;\n}\n.content { margin: 30pt; padding: 40pt; background: #ffffff; border-radius: 8pt; }\nh1 { color: #2d3748; font-size: 32pt; }\n.box {\n  background: #70ad47; padding: 20pt; border: 3px solid #5a8f37;\n  border-radius: 12pt; box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.25);\n}\n</style>\n</head>\n<body>\n<div class=\"content\">\n  <h1>Recipe Title</h1>\n  <ul>\n    <li><b>Item:</b> Description</li>\n  </ul>\n  <p>Text with <b>bold</b>, <i>italic</i>, <u>underline</u>.</p>\n  <div id=\"chart\" class=\"placeholder\" style=\"width: 350pt; height: 200pt;\"></div>\n\n  <!-- Text MUST be in <p> tags -->\n  <div class=\"box\">\n    <p>5</p>\n  </div>\n</div>\n</body>\n</html>\n```\n\n## Using the html2pptx Library\n\n### Dependencies\n\nThese libraries have been globally installed and are available to use:\n- `pptxgenjs`\n- `playwright`\n- `sharp`\n\n### Basic Usage\n\n```javascript\nconst pptxgen = require('pptxgenjs');\nconst html2pptx = require('./html2pptx');\n\nconst pptx = new pptxgen();\npptx.layout = 'LAYOUT_16x9';  // Must match HTML body dimensions\n\nconst { slide, placeholders } = await html2pptx('slide1.html', pptx);\n\n// Add chart to placeholder area\nif (placeholders.length > 0) {\n    slide.addChart(pptx.charts.LINE, chartData, placeholders[0]);\n}\n\nawait pptx.writeFile('output.pptx');\n```\n\n### API Reference\n\n#### Function Signature\n```javascript\nawait html2pptx(htmlFile, pres, options)\n```\n\n#### Parameters\n- `htmlFile` (string): Path to HTML file (absolute or relative)\n- `pres` (pptxgen): PptxGenJS presentation instance with layout already set\n- `options` (object, optional):\n  - `tmpDir` (string): Temporary directory for generated files (default: `process.env.TMPDIR || '/tmp'`)\n  - `slide` (object): Existing slide to reuse (default: creates new slide)\n\n#### Returns\n```javascript\n{\n    slide: pptxgenSlide,           // The created/updated slide\n    placeholders: [                 // Array of placeholder positions\n        { id: string, x: number, y: number, w: number, h: number },\n        ...\n    ]\n}\n```\n\n### Validation\n\nThe library automatically validates and collects all errors before throwing:\n\n1. **HTML dimensions must match presentation layout** - Reports dimension mismatches\n2. **Content must not overflow body** - Reports overflow with exact measurements\n3. **CSS gradients** - Reports unsupported gradient usage\n4. **Text element styling** - Reports backgrounds/borders/shadows on text elements (only allowed on divs)\n\n**All validation errors are collected and reported together** in a single error message, allowing you to fix all issues at once instead of one at a time.\n\n### Working with Placeholders\n\n```javascript\nconst { slide, placeholders } = await html2pptx('slide.html', pptx);\n\n// Use first placeholder\nslide.addChart(pptx.charts.BAR, data, placeholders[0]);\n\n// Find by ID\nconst chartArea = placeholders.find(p => p.id === 'chart-area');\nslide.addChart(pptx.charts.LINE, data, chartArea);\n```\n\n### Complete Example\n\n```javascript\nconst pptxgen = require('pptxgenjs');\nconst html2pptx = require('./html2pptx');\n\nasync function createPresentation() {\n    const pptx = new pptxgen();\n    pptx.layout = 'LAYOUT_16x9';\n    pptx.author = 'Your Name';\n    pptx.title = 'My Presentation';\n\n    // Slide 1: Title\n    const { slide: slide1 } = await html2pptx('slides/title.html', pptx);\n\n    // Slide 2: Content with chart\n    const { slide: slide2, placeholders } = await html2pptx('slides/data.html', pptx);\n\n    const chartData = [{\n        name: 'Sales',\n        labels: ['Q1', 'Q2', 'Q3', 'Q4'],\n        values: [4500, 5500, 6200, 7100]\n    }];\n\n    slide2.addChart(pptx.charts.BAR, chartData, {\n        ...placeholders[0],\n        showTitle: true,\n        title: 'Quarterly Sales',\n        showCatAxisTitle: true,\n        catAxisTitle: 'Quarter',\n        showValAxisTitle: true,\n        valAxisTitle: 'Sales ($000s)'\n    });\n\n    // Save\n    await pptx.writeFile({ fileName: 'presentation.pptx' });\n    console.log('Presentation created successfully!');\n}\n\ncreatePresentation().catch(console.error);\n```\n\n## Using PptxGenJS\n\nAfter converting HTML to slides with `html2pptx`, you'll use PptxGenJS to add dynamic content like charts, images, and additional elements.\n\n### ⚠️ Critical Rules\n\n#### Colors\n- **NEVER use `#` prefix** with hex colors in PptxGenJS - causes file corruption\n- ✅ Correct: `color: \"FF0000\"`, `fill: { color: \"0066CC\" }`\n- ❌ Wrong: `color: \"#FF0000\"` (breaks document)\n\n### Adding Images\n\nAlways calculate aspect ratios from actual image dimensions:\n\n```javascript\n// Get image dimensions: identify image.png | grep -o '[0-9]* x [0-9]*'\nconst imgWidth = 1860, imgHeight = 1519;  // From actual file\nconst aspectRatio = imgWidth / imgHeight;\n\nconst h = 3;  // Max height\nconst w = h * aspectRatio;\nconst x = (10 - w) / 2;  // Center on 16:9 slide\n\nslide.addImage({ path: \"chart.png\", x, y: 1.5, w, h });\n```\n\n### Adding Text\n\n```javascript\n// Rich text with formatting\nslide.addText([\n    { text: \"Bold \", options: { bold: true } },\n    { text: \"Italic \", options: { italic: true } },\n    { text: \"Normal\" }\n], {\n    x: 1, y: 2, w: 8, h: 1\n});\n```\n\n### Adding Shapes\n\n```javascript\n// Rectangle\nslide.addShape(pptx.shapes.RECTANGLE, {\n    x: 1, y: 1, w: 3, h: 2,\n    fill: { color: \"4472C4\" },\n    line: { color: \"000000\", width: 2 }\n});\n\n// Circle\nslide.addShape(pptx.shapes.OVAL, {\n    x: 5, y: 1, w: 2, h: 2,\n    fill: { color: \"ED7D31\" }\n});\n\n// Rounded rectangle\nslide.addShape(pptx.shapes.ROUNDED_RECTANGLE, {\n    x: 1, y: 4, w: 3, h: 1.5,\n    fill: { color: \"70AD47\" },\n    rectRadius: 0.2\n});\n```\n\n### Adding Charts\n\n**Required for most charts:** Axis labels using `catAxisTitle` (category) and `valAxisTitle` (value).\n\n**Chart Data Format:**\n- Use **single series with all labels** for simple bar/line charts\n- Each series creates a separate legend entry\n- Labels array defines X-axis values\n\n**Time Series Data - Choose Correct Granularity:**\n- **< 30 days**: Use daily grouping (e.g., \"10-01\", \"10-02\") - avoid monthly aggregation that creates single-point charts\n- **30-365 days**: Use monthly grouping (e.g., \"2024-01\", \"2024-02\")\n- **> 365 days**: Use yearly grouping (e.g., \"2023\", \"2024\")\n- **Validate**: Charts with only 1 data point likely indicate incorrect aggregation for the time period\n\n```javascript\nconst { slide, placeholders } = await html2pptx('slide.html', pptx);\n\n// CORRECT: Single series with all labels\nslide.addChart(pptx.charts.BAR, [{\n    name: \"Sales 2024\",\n    labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n    values: [4500, 5500, 6200, 7100]\n}], {\n    ...placeholders[0],  // Use placeholder position\n    barDir: 'col',       // 'col' = vertical bars, 'bar' = horizontal\n    showTitle: true,\n    title: 'Quarterly Sales',\n    showLegend: false,   // No legend needed for single series\n    // Required axis labels\n    showCatAxisTitle: true,\n    catAxisTitle: 'Quarter',\n    showValAxisTitle: true,\n    valAxisTitle: 'Sales ($000s)',\n    // Optional: Control scaling (adjust min based on data range for better visualization)\n    valAxisMaxVal: 8000,\n    valAxisMinVal: 0,  // Use 0 for counts/amounts; for clustered data (e.g., 4500-7100), consider starting closer to min value\n    valAxisMajorUnit: 2000,  // Control y-axis label spacing to prevent crowding\n    catAxisLabelRotate: 45,  // Rotate labels if crowded\n    dataLabelPosition: 'outEnd',\n    dataLabelColor: '000000',\n    // Use single color for single-series charts\n    chartColors: [\"4472C4\"]  // All bars same color\n});\n```\n\n#### Scatter Chart\n\n**IMPORTANT**: Scatter chart data format is unusual - first series contains X-axis values, subsequent series contain Y-values:\n\n```javascript\n// Prepare data\nconst data1 = [{ x: 10, y: 20 }, { x: 15, y: 25 }, { x: 20, y: 30 }];\nconst data2 = [{ x: 12, y: 18 }, { x: 18, y: 22 }];\n\nconst allXValues = [...data1.map(d => d.x), ...data2.map(d => d.x)];\n\nslide.addChart(pptx.charts.SCATTER, [\n    { name: 'X-Axis', values: allXValues },  // First series = X values\n    { name: 'Series 1', values: data1.map(d => d.y) },  // Y values only\n    { name: 'Series 2', values: data2.map(d => d.y) }   // Y values only\n], {\n    x: 1, y: 1, w: 8, h: 4,\n    lineSize: 0,  // 0 = no connecting lines\n    lineDataSymbol: 'circle',\n    lineDataSymbolSize: 6,\n    showCatAxisTitle: true,\n    catAxisTitle: 'X Axis',\n    showValAxisTitle: true,\n    valAxisTitle: 'Y Axis',\n    chartColors: [\"4472C4\", \"ED7D31\"]\n});\n```\n\n#### Line Chart\n\n```javascript\nslide.addChart(pptx.charts.LINE, [{\n    name: \"Temperature\",\n    labels: [\"Jan\", \"Feb\", \"Mar\", \"Apr\"],\n    values: [32, 35, 42, 55]\n}], {\n    x: 1, y: 1, w: 8, h: 4,\n    lineSize: 4,\n    lineSmooth: true,\n    // Required axis labels\n    showCatAxisTitle: true,\n    catAxisTitle: 'Month',\n    showValAxisTitle: true,\n    valAxisTitle: 'Temperature (°F)',\n    // Optional: Y-axis range (set min based on data range for better visualization)\n    valAxisMinVal: 0,     // For ranges starting at 0 (counts, percentages, etc.)\n    valAxisMaxVal: 60,\n    valAxisMajorUnit: 20,  // Control y-axis label spacing to prevent crowding (e.g., 10, 20, 25)\n    // valAxisMinVal: 30,  // PREFERRED: For data clustered in a range (e.g., 32-55 or ratings 3-5), start axis closer to min value to show variation\n    // Optional: Chart colors\n    chartColors: [\"4472C4\", \"ED7D31\", \"A5A5A5\"]\n});\n```\n\n#### Pie Chart (No Axis Labels Required)\n\n**CRITICAL**: Pie charts require a **single data series** with all categories in the `labels` array and corresponding values in the `values` array.\n\n```javascript\nslide.addChart(pptx.charts.PIE, [{\n    name: \"Market Share\",\n    labels: [\"Product A\", \"Product B\", \"Other\"],  // All categories in one array\n    values: [35, 45, 20]  // All values in one array\n}], {\n    x: 2, y: 1, w: 6, h: 4,\n    showPercent: true,\n    showLegend: true,\n    legendPos: 'r',  // right\n    chartColors: [\"4472C4\", \"ED7D31\", \"A5A5A5\"]\n});\n```\n\n#### Multiple Data Series\n\n```javascript\nslide.addChart(pptx.charts.LINE, [\n    {\n        name: \"Product A\",\n        labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n        values: [10, 20, 30, 40]\n    },\n    {\n        name: \"Product B\",\n        labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n        values: [15, 25, 20, 35]\n    }\n], {\n    x: 1, y: 1, w: 8, h: 4,\n    showCatAxisTitle: true,\n    catAxisTitle: 'Quarter',\n    showValAxisTitle: true,\n    valAxisTitle: 'Revenue ($M)'\n});\n```\n\n### Chart Colors\n\n**CRITICAL**: Use hex colors **without** the `#` prefix - including `#` causes file corruption.\n\n**Align chart colors with your chosen design palette**, ensuring sufficient contrast and distinctiveness for data visualization. Adjust colors for:\n- Strong contrast between adjacent series\n- Readability against slide backgrounds\n- Accessibility (avoid red-green only combinations)\n\n```javascript\n// Example: Ocean palette-inspired chart colors (adjusted for contrast)\nconst chartColors = [\"16A085\", \"FF6B9D\", \"2C3E50\", \"F39C12\", \"9B59B6\"];\n\n// Single-series chart: Use one color for all bars/points\nslide.addChart(pptx.charts.BAR, [{\n    name: \"Sales\",\n    labels: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n    values: [4500, 5500, 6200, 7100]\n}], {\n    ...placeholders[0],\n    chartColors: [\"16A085\"],  // All bars same color\n    showLegend: false\n});\n\n// Multi-series chart: Each series gets a different color\nslide.addChart(pptx.charts.LINE, [\n    { name: \"Product A\", labels: [\"Q1\", \"Q2\", \"Q3\"], values: [10, 20, 30] },\n    { name: \"Product B\", labels: [\"Q1\", \"Q2\", \"Q3\"], values: [15, 25, 20] }\n], {\n    ...placeholders[0],\n    chartColors: [\"16A085\", \"FF6B9D\"]  // One color per series\n});\n```\n\n### Adding Tables\n\nTables can be added with basic or advanced formatting:\n\n#### Basic Table\n\n```javascript\nslide.addTable([\n    [\"Header 1\", \"Header 2\", \"Header 3\"],\n    [\"Row 1, Col 1\", \"Row 1, Col 2\", \"Row 1, Col 3\"],\n    [\"Row 2, Col 1\", \"Row 2, Col 2\", \"Row 2, Col 3\"]\n], {\n    x: 0.5,\n    y: 1,\n    w: 9,\n    h: 3,\n    border: { pt: 1, color: \"999999\" },\n    fill: { color: \"F1F1F1\" }\n});\n```\n\n#### Table with Custom Formatting\n\n```javascript\nconst tableData = [\n    // Header row with custom styling\n    [\n        { text: \"Product\", options: { fill: { color: \"4472C4\" }, color: \"FFFFFF\", bold: true } },\n        { text: \"Revenue\", options: { fill: { color: \"4472C4\" }, color: \"FFFFFF\", bold: true } },\n        { text: \"Growth\", options: { fill: { color: \"4472C4\" }, color: \"FFFFFF\", bold: true } }\n    ],\n    // Data rows\n    [\"Product A\", \"$50M\", \"+15%\"],\n    [\"Product B\", \"$35M\", \"+22%\"],\n    [\"Product C\", \"$28M\", \"+8%\"]\n];\n\nslide.addTable(tableData, {\n    x: 1,\n    y: 1.5,\n    w: 8,\n    h: 3,\n    colW: [3, 2.5, 2.5],  // Column widths\n    rowH: [0.5, 0.6, 0.6, 0.6],  // Row heights\n    border: { pt: 1, color: \"CCCCCC\" },\n    align: \"center\",\n    valign: \"middle\",\n    fontSize: 14\n});\n```\n\n#### Table with Merged Cells\n\n```javascript\nconst mergedTableData = [\n    [\n        { text: \"Q1 Results\", options: { colspan: 3, fill: { color: \"4472C4\" }, color: \"FFFFFF\", bold: true } }\n    ],\n    [\"Product\", \"Sales\", \"Market Share\"],\n    [\"Product A\", \"$25M\", \"35%\"],\n    [\"Product B\", \"$18M\", \"25%\"]\n];\n\nslide.addTable(mergedTableData, {\n    x: 1,\n    y: 1,\n    w: 8,\n    h: 2.5,\n    colW: [3, 2.5, 2.5],\n    border: { pt: 1, color: \"DDDDDD\" }\n});\n```\n\n### Table Options\n\nCommon table options:\n- `x, y, w, h` - Position and size\n- `colW` - Array of column widths (in inches)\n- `rowH` - Array of row heights (in inches)\n- `border` - Border style: `{ pt: 1, color: \"999999\" }`\n- `fill` - Background color (no # prefix)\n- `align` - Text alignment: \"left\", \"center\", \"right\"\n- `valign` - Vertical alignment: \"top\", \"middle\", \"bottom\"\n- `fontSize` - Text size\n- `autoPage` - Auto-create new slides if content overflows"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  xmlns:cdr=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n    schemaLocation=\"dml-chartDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Double\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedInt\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumData\">\n    <xsd:sequence>\n      <xsd:element name=\"formatCode\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_NumVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numCache\" type=\"CT_NumData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrVal\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strCache\" type=\"CT_StrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"rich\" type=\"a:CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLanguageID\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_StrVal\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrData\">\n    <xsd:sequence>\n      <xsd:element name=\"ptCount\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MultiLvlStrRef\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"multiLvlStrCache\" type=\"CT_MultiLvlStrData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AxDataSource\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"multiLvlStrRef\" type=\"CT_MultiLvlStrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numRef\" type=\"CT_NumRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"numLit\" type=\"CT_NumData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"strLit\" type=\"CT_StrData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerTx\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"strRef\" type=\"CT_StrRef\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutTarget\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inner\"/>\n      <xsd:enumeration value=\"outer\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutTarget\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutTarget\" default=\"outer\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"edge\"/>\n      <xsd:enumeration value=\"factor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LayoutMode\">\n    <xsd:attribute name=\"val\" type=\"ST_LayoutMode\" default=\"factor\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualLayout\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutTarget\" type=\"CT_LayoutTarget\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hMode\" type=\"CT_LayoutMode\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"x\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"w\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"h\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Layout\">\n    <xsd:sequence>\n      <xsd:element name=\"manualLayout\" type=\"CT_ManualLayout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Title\">\n    <xsd:sequence>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotX\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-90\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotX\">\n    <xsd:attribute name=\"val\" type=\"ST_RotX\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HPercent\">\n    <xsd:union memberTypes=\"ST_HPercentWithSymbol ST_HPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_HPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RotY\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RotY\">\n    <xsd:attribute name=\"val\" type=\"ST_RotY\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DepthPercent\">\n    <xsd:union memberTypes=\"ST_DepthPercentWithSymbol ST_DepthPercentUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentWithSymbol\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DepthPercentUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"20\"/>\n      <xsd:maxInclusive value=\"2000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DepthPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_DepthPercent\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Perspective\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"240\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perspective\">\n    <xsd:attribute name=\"val\" type=\"ST_Perspective\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_View3D\">\n    <xsd:sequence>\n      <xsd:element name=\"rotX\" type=\"CT_RotX\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hPercent\" type=\"CT_HPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rotY\" type=\"CT_RotY\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"depthPercent\" type=\"CT_DepthPercent\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rAngAx\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"perspective\" type=\"CT_Perspective\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface\">\n    <xsd:sequence>\n      <xsd:element name=\"thickness\" type=\"CT_Thickness\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Thickness\">\n    <xsd:union memberTypes=\"ST_ThicknessPercent xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ThicknessPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"([0-9]+)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Thickness\">\n    <xsd:attribute name=\"val\" type=\"ST_Thickness\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DTable\">\n    <xsd:sequence>\n      <xsd:element name=\"showHorzBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVertBorder\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showOutline\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showKeys\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GapAmount\">\n    <xsd:union memberTypes=\"ST_GapAmountPercent ST_GapAmountUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GapAmountUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"500\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GapAmount\">\n    <xsd:attribute name=\"val\" type=\"ST_GapAmount\" default=\"150%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Overlap\">\n    <xsd:union memberTypes=\"ST_OverlapPercent ST_OverlapByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"(-?0*(([0-9])|([1-9][0-9])|100))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OverlapByte\">\n    <xsd:restriction base=\"xsd:byte\">\n      <xsd:minInclusive value=\"-100\"/>\n      <xsd:maxInclusive value=\"100\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Overlap\">\n    <xsd:attribute name=\"val\" type=\"ST_Overlap\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BubbleScale\">\n    <xsd:union memberTypes=\"ST_BubbleScalePercent ST_BubbleScaleUInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-2][0-9][0-9])|300)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BubbleScaleUInt\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"300\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BubbleScale\">\n    <xsd:attribute name=\"val\" type=\"ST_BubbleScale\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SizeRepresents\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"w\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SizeRepresents\">\n    <xsd:attribute name=\"val\" type=\"ST_SizeRepresents\" default=\"area\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FirstSliceAng\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"360\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FirstSliceAng\">\n    <xsd:attribute name=\"val\" type=\"ST_FirstSliceAng\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HoleSize\">\n    <xsd:union memberTypes=\"ST_HoleSizePercent ST_HoleSizeUByte\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*([1-9]|([1-8][0-9])|90)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HoleSizeUByte\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"90\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HoleSize\">\n    <xsd:attribute name=\"val\" type=\"ST_HoleSize\" default=\"10%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SplitType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"val\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SplitType\">\n    <xsd:attribute name=\"val\" type=\"ST_SplitType\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustSplit\">\n    <xsd:sequence>\n      <xsd:element name=\"secondPiePt\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SecondPieSize\">\n    <xsd:union memberTypes=\"ST_SecondPieSizePercent ST_SecondPieSizeUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([5-9])|([1-9][0-9])|(1[0-9][0-9])|200)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondPieSizeUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"5\"/>\n      <xsd:maxInclusive value=\"200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SecondPieSize\">\n    <xsd:attribute name=\"val\" type=\"ST_SecondPieSize\" default=\"75%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceLinked\" type=\"xsd:boolean\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblAlgn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblAlgn\">\n    <xsd:attribute name=\"val\" type=\"ST_LblAlgn\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"inBase\"/>\n      <xsd:enumeration value=\"inEnd\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"outEnd\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_DLblPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_DLblShared\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLblPos\" type=\"CT_DLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLegendKey\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showVal\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showCatName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showSerName\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPercent\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showBubbleSize\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"separator\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"Group_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbl\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"Group_DLbls\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_DLblShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showLeaderLines\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"leaderLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DLbls\">\n    <xsd:sequence>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"Group_DLbls\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"picture\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"star\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerStyle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MarkerSize\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"72\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MarkerSize\">\n    <xsd:attribute name=\"val\" type=\"ST_MarkerSize\" default=\"5\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"symbol\" type=\"CT_MarkerStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"size\" type=\"CT_MarkerSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TrendlineType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"exp\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"log\"/>\n      <xsd:enumeration value=\"movingAvg\"/>\n      <xsd:enumeration value=\"poly\"/>\n      <xsd:enumeration value=\"power\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TrendlineType\">\n    <xsd:attribute name=\"val\" type=\"ST_TrendlineType\" default=\"linear\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Order\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"6\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Order\">\n    <xsd:attribute name=\"val\" type=\"ST_Order\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Period\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Period\">\n    <xsd:attribute name=\"val\" type=\"ST_Period\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrendlineLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Trendline\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineType\" type=\"CT_TrendlineType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_Order\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"period\" type=\"CT_Period\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backward\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"intercept\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispRSqr\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispEq\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendlineLbl\" type=\"CT_TrendlineLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrDir\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrDir\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrBarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"minus\"/>\n      <xsd:enumeration value=\"plus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrBarType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrBarType\" default=\"both\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ErrValType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"fixedVal\"/>\n      <xsd:enumeration value=\"percentage\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdErr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ErrValType\">\n    <xsd:attribute name=\"val\" type=\"ST_ErrValType\" default=\"fixedVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ErrBars\">\n    <xsd:sequence>\n      <xsd:element name=\"errDir\" type=\"CT_ErrDir\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errBarType\" type=\"CT_ErrBarType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"errValType\" type=\"CT_ErrValType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noEndCap\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minus\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBar\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UpDownBars\">\n    <xsd:sequence>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"downBars\" type=\"CT_UpDownBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SerShared\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"order\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_SerTx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AreaSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureOptions\" type=\"CT_PictureOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PieSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"explosion\" type=\"CT_UnsignedInt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invertIfNegative\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dPt\" type=\"CT_DPt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trendline\" type=\"CT_Trendline\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"errBars\" type=\"CT_ErrBars\" minOccurs=\"0\" maxOccurs=\"2\"/>\n      <xsd:element name=\"xVal\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"yVal\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleSize\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SurfaceSer\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SerShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cat\" type=\"CT_AxDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"val\" type=\"CT_NumDataSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Grouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Grouping\">\n    <xsd:attribute name=\"val\" type=\"ST_Grouping\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartLines\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smooth\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StockChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ser\" type=\"CT_LineSer\" minOccurs=\"3\" maxOccurs=\"4\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hiLowLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"upDownBars\" type=\"CT_UpDownBars\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ScatterStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineMarker\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"smooth\"/>\n      <xsd:enumeration value=\"smoothMarker\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ScatterStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_ScatterStyle\" default=\"marker\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ScatterChart\">\n    <xsd:sequence>\n      <xsd:element name=\"scatterStyle\" type=\"CT_ScatterStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_ScatterSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RadarStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"marker\"/>\n      <xsd:enumeration value=\"filled\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RadarStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_RadarStyle\" default=\"standard\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadarChart\">\n    <xsd:sequence>\n      <xsd:element name=\"radarStyle\" type=\"CT_RadarStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_RadarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"percentStacked\"/>\n      <xsd:enumeration value=\"clustered\"/>\n      <xsd:enumeration value=\"standard\"/>\n      <xsd:enumeration value=\"stacked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarGrouping\">\n    <xsd:attribute name=\"val\" type=\"ST_BarGrouping\" default=\"clustered\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BarDir\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BarDir\">\n    <xsd:attribute name=\"val\" type=\"ST_BarDir\" default=\"col\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shape\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cone\"/>\n      <xsd:enumeration value=\"coneToMax\"/>\n      <xsd:enumeration value=\"box\"/>\n      <xsd:enumeration value=\"cylinder\"/>\n      <xsd:enumeration value=\"pyramid\"/>\n      <xsd:enumeration value=\"pyramidToMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:attribute name=\"val\" type=\"ST_Shape\" default=\"box\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_BarChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"barDir\" type=\"CT_BarDir\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grouping\" type=\"CT_BarGrouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BarSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_BarChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlap\" type=\"CT_Overlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BarChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AreaChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"grouping\" type=\"CT_Grouping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_AreaSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dropLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AreaChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Area3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AreaChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapDepth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PieChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_PieSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_PieChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pie3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DoughnutChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstSliceAng\" type=\"CT_FirstSliceAng\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"holeSize\" type=\"CT_HoleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_OfPieType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"bar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OfPieType\">\n    <xsd:attribute name=\"val\" type=\"ST_OfPieType\" default=\"pie\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfPieChart\">\n    <xsd:sequence>\n      <xsd:element name=\"ofPieType\" type=\"CT_OfPieType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PieChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gapWidth\" type=\"CT_GapAmount\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitType\" type=\"CT_SplitType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"splitPos\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custSplit\" type=\"CT_CustSplit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"secondPieSize\" type=\"CT_SecondPieSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"serLines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BubbleChart\">\n    <xsd:sequence>\n      <xsd:element name=\"varyColors\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_BubbleSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dLbls\" type=\"CT_DLbls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubble3D\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bubbleScale\" type=\"CT_BubbleScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showNegBubbles\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sizeRepresents\" type=\"CT_SizeRepresents\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BandFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"bandFmt\" type=\"CT_BandFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SurfaceChartShared\">\n    <xsd:sequence>\n      <xsd:element name=\"wireframe\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ser\" type=\"CT_SurfaceSer\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"bandFmts\" type=\"CT_BandFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SurfaceChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"2\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Surface3DChart\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SurfaceChartShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"3\" maxOccurs=\"3\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxPos\">\n    <xsd:attribute name=\"val\" type=\"ST_AxPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Crosses\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"autoZero\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Crosses\">\n    <xsd:attribute name=\"val\" type=\"ST_Crosses\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CrossBetween\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"midCat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CrossBetween\">\n    <xsd:attribute name=\"val\" type=\"ST_CrossBetween\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"out\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickMark\">\n    <xsd:attribute name=\"val\" type=\"ST_TickMark\" default=\"cross\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TickLblPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"high\"/>\n      <xsd:enumeration value=\"low\"/>\n      <xsd:enumeration value=\"nextTo\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TickLblPos\">\n    <xsd:attribute name=\"val\" type=\"ST_TickLblPos\" default=\"nextTo\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Skip\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Skip\">\n    <xsd:attribute name=\"val\" type=\"ST_Skip\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TimeUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TimeUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_TimeUnit\" default=\"days\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AxisUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AxisUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_AxisUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BuiltInUnit\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hundreds\"/>\n      <xsd:enumeration value=\"thousands\"/>\n      <xsd:enumeration value=\"tenThousands\"/>\n      <xsd:enumeration value=\"hundredThousands\"/>\n      <xsd:enumeration value=\"millions\"/>\n      <xsd:enumeration value=\"tenMillions\"/>\n      <xsd:enumeration value=\"hundredMillions\"/>\n      <xsd:enumeration value=\"billions\"/>\n      <xsd:enumeration value=\"trillions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BuiltInUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_BuiltInUnit\" default=\"thousands\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stretch\"/>\n      <xsd:enumeration value=\"stack\"/>\n      <xsd:enumeration value=\"stackScale\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureFormat\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureFormat\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PictureStackUnit\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minExclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PictureStackUnit\">\n    <xsd:attribute name=\"val\" type=\"ST_PictureStackUnit\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureOptions\">\n    <xsd:sequence>\n      <xsd:element name=\"applyToFront\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToSides\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"applyToEnd\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureFormat\" type=\"CT_PictureFormat\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pictureStackUnit\" type=\"CT_PictureStackUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnitsLbl\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tx\" type=\"CT_Tx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DispUnits\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"custUnit\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"builtInUnit\" type=\"CT_BuiltInUnit\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dispUnitsLbl\" type=\"CT_DispUnitsLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"maxMin\"/>\n      <xsd:enumeration value=\"minMax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Orientation\">\n    <xsd:attribute name=\"val\" type=\"ST_Orientation\" default=\"minMax\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LogBase\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"2\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LogBase\">\n    <xsd:attribute name=\"val\" type=\"ST_LogBase\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scaling\">\n    <xsd:sequence>\n      <xsd:element name=\"logBase\" type=\"CT_LogBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"orientation\" type=\"CT_Orientation\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"max\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"min\" type=\"CT_Double\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LblOffset\">\n    <xsd:union memberTypes=\"ST_LblOffsetPercent ST_LblOffsetUShort\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetPercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(([0-9])|([1-9][0-9])|([1-9][0-9][0-9])|1000)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LblOffsetUShort\">\n    <xsd:restriction base=\"xsd:unsignedShort\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"1000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LblOffset\">\n    <xsd:attribute name=\"val\" type=\"ST_LblOffset\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_AxShared\">\n    <xsd:sequence>\n      <xsd:element name=\"axId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scaling\" type=\"CT_Scaling\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"axPos\" type=\"CT_AxPos\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorGridlines\" type=\"CT_ChartLines\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTickMark\" type=\"CT_TickMark\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblPos\" type=\"CT_TickLblPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossAx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"crosses\" type=\"CT_Crosses\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"crossesAt\" type=\"CT_Double\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CatAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblAlgn\" type=\"CT_LblAlgn\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"noMultiLvlLbl\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"auto\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lblOffset\" type=\"CT_LblOffset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"baseTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorTimeUnit\" type=\"CT_TimeUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SerAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickLblSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tickMarkSkip\" type=\"CT_Skip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ValAx\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_AxShared\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"crossBetween\" type=\"CT_CrossBetween\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"majorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorUnit\" type=\"CT_AxisUnit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispUnits\" type=\"CT_DispUnits\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PlotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"areaChart\" type=\"CT_AreaChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"area3DChart\" type=\"CT_Area3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lineChart\" type=\"CT_LineChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"line3DChart\" type=\"CT_Line3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"stockChart\" type=\"CT_StockChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"radarChart\" type=\"CT_RadarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"scatterChart\" type=\"CT_ScatterChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pieChart\" type=\"CT_PieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"pie3DChart\" type=\"CT_Pie3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"doughnutChart\" type=\"CT_DoughnutChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"barChart\" type=\"CT_BarChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bar3DChart\" type=\"CT_Bar3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ofPieChart\" type=\"CT_OfPieChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surfaceChart\" type=\"CT_SurfaceChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"surface3DChart\" type=\"CT_Surface3DChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"bubbleChart\" type=\"CT_BubbleChart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"valAx\" type=\"CT_ValAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"catAx\" type=\"CT_CatAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"dateAx\" type=\"CT_DateAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"serAx\" type=\"CT_SerAx\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"dTable\" type=\"CT_DTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmt\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"marker\" type=\"CT_Marker\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dLbl\" type=\"CT_DLbl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotFmt\" type=\"CT_PivotFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LegendPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LegendPos\">\n    <xsd:attribute name=\"val\" type=\"ST_LegendPos\" default=\"r\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LegendEntryData\">\n    <xsd:sequence>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LegendEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"idx\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"delete\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:group ref=\"EG_LegendEntryData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Legend\">\n    <xsd:sequence>\n      <xsd:element name=\"legendPos\" type=\"CT_LegendPos\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legendEntry\" type=\"CT_LegendEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"layout\" type=\"CT_Layout\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"overlay\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DispBlanksAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"gap\"/>\n      <xsd:enumeration value=\"zero\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DispBlanksAs\">\n    <xsd:attribute name=\"val\" type=\"ST_DispBlanksAs\" default=\"zero\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chart\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoTitleDeleted\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotFmts\" type=\"CT_PivotFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"view3D\" type=\"CT_View3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"floor\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sideWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backWall\" type=\"CT_Surface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotArea\" type=\"CT_PlotArea\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legend\" type=\"CT_Legend\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"plotVisOnly\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dispBlanksAs\" type=\"CT_DispBlanksAs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showDLblsOverMax\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:unsignedByte\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"48\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSource\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtId\" type=\"CT_UnsignedInt\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Protection\">\n    <xsd:sequence>\n      <xsd:element name=\"chartObject\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"data\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formatting\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userInterface\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"l\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageSetupOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ExternalData\">\n    <xsd:sequence>\n      <xsd:element name=\"autoUpdate\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_PageSetupOrientation\" use=\"optional\"\n      default=\"default\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:int\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartSpace\">\n    <xsd:sequence>\n      <xsd:element name=\"date1904\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lang\" type=\"CT_TextLanguageID\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"roundedCorners\" type=\"CT_Boolean\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotSource\" type=\"CT_PivotSource\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_Protection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chart\" type=\"CT_Chart\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalData\" type=\"CT_ExternalData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printSettings\" type=\"CT_PrintSettings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"userShapes\" type=\"CT_RelId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"chartSpace\" type=\"CT_ChartSpace\"/>\n  <xsd:element name=\"userShapes\" type=\"cdr:CT_Drawing\"/>\n  <xsd:element name=\"chart\" type=\"CT_RelId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_MarkerCoordinate\">\n    <xsd:restriction base=\"xsd:double\">\n      <xsd:minInclusive value=\"0.0\"/>\n      <xsd:maxInclusive value=\"1.0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"y\" type=\"ST_MarkerCoordinate\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsSizeAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"relSizeAnchor\" type=\"CT_RelSizeAnchor\"/>\n      <xsd:element name=\"absSizeAnchor\" type=\"CT_AbsSizeAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_CTName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_CTCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ClrAppMethod\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"span\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HueDir\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"meth\" type=\"ST_ClrAppMethod\" use=\"optional\" default=\"span\"/>\n    <xsd:attribute name=\"hueDir\" type=\"ST_HueDir\" use=\"optional\" default=\"cw\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CTStyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"fillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"linClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txLinClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txFillClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txEffectClrLst\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorTransform\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_CTStyleLabel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDef\" type=\"CT_ColorTransform\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_CTName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_CTDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_CTCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\"/>\n  <xsd:complexType name=\"CT_ColorTransformHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"colorsDefHdr\" type=\"CT_ColorTransformHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"colorsDefHdrLst\" type=\"CT_ColorTransformHeaderLst\"/>\n  <xsd:simpleType name=\"ST_PtType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pt\">\n    <xsd:sequence>\n      <xsd:element name=\"prSet\" type=\"CT_ElemPropSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PtType\" use=\"optional\" default=\"node\"/>\n    <xsd:attribute name=\"cxnId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PtList\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_Pt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CxnType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parOf\"/>\n      <xsd:enumeration value=\"presOf\"/>\n      <xsd:enumeration value=\"presParOf\"/>\n      <xsd:enumeration value=\"unknownRelationship\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cxn\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"modelId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_CxnType\" use=\"optional\" default=\"parOf\"/>\n    <xsd:attribute name=\"srcId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"destId\" type=\"ST_ModelId\" use=\"required\"/>\n    <xsd:attribute name=\"srcOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"destOrd\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"parTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sibTransId\" type=\"ST_ModelId\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"presId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CxnList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_Cxn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataModel\">\n    <xsd:sequence>\n      <xsd:element name=\"ptLst\" type=\"CT_PtList\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_CxnList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"dataModel\" type=\"CT_DataModel\"/>\n  <xsd:attributeGroup name=\"AG_IteratorAttributes\">\n    <xsd:attribute name=\"axis\" type=\"ST_AxisTypes\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementTypes\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"hideLastTrans\" type=\"ST_Booleans\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"st\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cnt\" type=\"ST_UnsignedInts\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"step\" type=\"ST_Ints\" use=\"optional\" default=\"1\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintAttributes\">\n    <xsd:attribute name=\"type\" type=\"ST_ConstraintType\" use=\"required\"/>\n    <xsd:attribute name=\"for\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"forName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ptType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ConstraintRefAttributes\">\n    <xsd:attribute name=\"refType\" type=\"ST_ConstraintType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"refFor\" type=\"ST_ConstraintRelationship\" use=\"optional\" default=\"self\"/>\n    <xsd:attribute name=\"refForName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"refPtType\" type=\"ST_ElementType\" use=\"optional\" default=\"all\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_Constraint\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ConstraintRefAttributes\"/>\n    <xsd:attribute name=\"op\" type=\"ST_BoolOperator\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Constraints\">\n    <xsd:sequence>\n      <xsd:element name=\"constr\" type=\"CT_Constraint\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumericRule\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ConstraintAttributes\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"fact\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:double\" use=\"optional\" default=\"NaN\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"rule\" type=\"CT_NumericRule\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationOf\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LayoutShapeType\" final=\"restriction\">\n    <xsd:union memberTypes=\"a:ST_ShapeType ST_OutputShapeType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index1\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Adj\">\n    <xsd:attribute name=\"idx\" type=\"ST_Index1\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjLst\">\n    <xsd:sequence>\n      <xsd:element name=\"adj\" type=\"CT_Adj\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"adjLst\" type=\"CT_AdjLst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"type\" type=\"ST_LayoutShapeType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute ref=\"r:blip\" use=\"optional\"/>\n    <xsd:attribute name=\"zOrderOff\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hideGeom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lkTxEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"blipPhldr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"type\" type=\"ST_ParameterId\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ParameterVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Algorithm\">\n    <xsd:sequence>\n      <xsd:element name=\"param\" type=\"CT_Parameter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_AlgorithmType\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutNode\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"varLst\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"styleLbl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"chOrder\" type=\"ST_ChildOrderType\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"moveWith\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ForEach\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"ref\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_When\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attributeGroup ref=\"AG_IteratorAttributes\"/>\n    <xsd:attribute name=\"func\" type=\"ST_FunctionType\" use=\"required\"/>\n    <xsd:attribute name=\"arg\" type=\"ST_FunctionArgument\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"op\" type=\"ST_FunctionOperator\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FunctionValue\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Otherwise\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"alg\" type=\"CT_Algorithm\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shape\" type=\"CT_Shape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"presOf\" type=\"CT_PresentationOf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"constrLst\" type=\"CT_Constraints\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ruleLst\" type=\"CT_Rules\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"forEach\" type=\"CT_ForEach\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"choose\" type=\"CT_Choose\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Choose\">\n    <xsd:sequence>\n      <xsd:element name=\"if\" type=\"CT_When\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"else\" type=\"CT_Otherwise\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SampleData\">\n    <xsd:sequence>\n      <xsd:element name=\"dataModel\" type=\"CT_DataModel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useDef\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Category\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Categories\">\n    <xsd:sequence>\n      <xsd:element name=\"cat\" type=\"CT_Category\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Name\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Description\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DiagramDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"sampData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"clrData\" type=\"CT_SampleData\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutNode\" type=\"CT_LayoutNode\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDef\" type=\"CT_DiagramDefinition\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_Name\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_Description\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_Categories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defStyle\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_DiagramDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"layoutDefHdr\" type=\"CT_DiagramDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"layoutDefHdrLst\" type=\"CT_DiagramDefinitionHeaderLst\"/>\n  <xsd:complexType name=\"CT_RelIds\">\n    <xsd:attribute ref=\"r:dm\" use=\"required\"/>\n    <xsd:attribute ref=\"r:lo\" use=\"required\"/>\n    <xsd:attribute ref=\"r:qs\" use=\"required\"/>\n    <xsd:attribute ref=\"r:cs\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"relIds\" type=\"CT_RelIds\"/>\n  <xsd:simpleType name=\"ST_ParameterVal\">\n    <xsd:union\n      memberTypes=\"ST_DiagramHorizontalAlignment ST_VerticalAlignment ST_ChildDirection ST_ChildAlignment ST_SecondaryChildAlignment ST_LinearDirection ST_SecondaryLinearDirection ST_StartingElement ST_BendPoint ST_ConnectorRouting ST_ArrowheadStyle ST_ConnectorDimension ST_RotationPath ST_CenterShapeMapping ST_NodeHorizontalAlignment ST_NodeVerticalAlignment ST_FallbackDimension ST_TextDirection ST_PyramidAccentPosition ST_PyramidAccentTextMargin ST_TextBlockDirection ST_TextAnchorHorizontal ST_TextAnchorVertical ST_DiagramTextAlignment ST_AutoTextRotation ST_GrowDirection ST_FlowDirection ST_ContinueDirection ST_Breakpoint ST_Offset ST_HierarchyAlignment xsd:int xsd:double xsd:boolean xsd:string ST_ConnectorPoint\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ModelId\">\n    <xsd:union memberTypes=\"xsd:int s:ST_Guid\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrSetCustVal\">\n    <xsd:union memberTypes=\"s:ST_Percentage xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ElemPropSet\">\n    <xsd:sequence>\n      <xsd:element name=\"presLayoutVars\" type=\"CT_LayoutVariablePropertySet\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"presAssocID\" type=\"ST_ModelId\" use=\"optional\"/>\n    <xsd:attribute name=\"presName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleLbl\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleIdx\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presStyleCnt\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"loTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"loCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"qsCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csTypeId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"csCatId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coherent3DOff\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"phldrT\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"phldr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custAng\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipVert\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custFlipHor\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzX\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custSzY\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custScaleY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custT\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborX\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custLinFactNeighborY\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleRad\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n    <xsd:attribute name=\"custRadScaleInc\" type=\"ST_PrSetCustVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"rev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierBranchStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"hang\"/>\n      <xsd:enumeration value=\"std\"/>\n      <xsd:enumeration value=\"init\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimOneStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"branch\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimLvlStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"lvl\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OrgChart\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NodeCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChildMax\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChildPref\">\n    <xsd:attribute name=\"val\" type=\"ST_NodeCount\" default=\"-1\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BulletEnabled\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" default=\"false\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Direction\">\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" default=\"norm\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierBranchStyle\">\n    <xsd:attribute name=\"val\" type=\"ST_HierBranchStyle\" default=\"std\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimOne\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimOneStr\" default=\"one\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimLvl\">\n    <xsd:attribute name=\"val\" type=\"ST_AnimLvlStr\" default=\"none\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ResizeHandlesStr\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"rel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ResizeHandles\">\n    <xsd:attribute name=\"val\" type=\"ST_ResizeHandlesStr\" default=\"rel\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LayoutVariablePropertySet\">\n    <xsd:sequence>\n      <xsd:element name=\"orgChart\" type=\"CT_OrgChart\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chMax\" type=\"CT_ChildMax\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chPref\" type=\"CT_ChildPref\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bulletEnabled\" type=\"CT_BulletEnabled\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dir\" type=\"CT_Direction\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hierBranch\" type=\"CT_HierBranchStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animOne\" type=\"CT_AnimOne\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"animLvl\" type=\"CT_AnimLvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"resizeHandles\" type=\"CT_ResizeHandles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDName\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDDescription\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategory\">\n    <xsd:attribute name=\"type\" type=\"xsd:anyURI\" use=\"required\"/>\n    <xsd:attribute name=\"pri\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SDCategories\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"cat\" type=\"CT_SDCategory\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextProps\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleLabel\">\n    <xsd:sequence>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"a:CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txPr\" type=\"CT_TextProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"scene3d\" type=\"a:CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"styleLbl\" type=\"CT_StyleLabel\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDef\" type=\"CT_StyleDefinition\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"title\" type=\"CT_SDName\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"desc\" type=\"CT_SDDescription\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"catLst\" type=\"CT_SDCategories\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"minVer\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"resId\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\"/>\n  <xsd:complexType name=\"CT_StyleDefinitionHeaderLst\">\n    <xsd:sequence>\n      <xsd:element name=\"styleDefHdr\" type=\"CT_StyleDefinitionHeader\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"styleDefHdrLst\" type=\"CT_StyleDefinitionHeaderLst\"/>\n  <xsd:simpleType name=\"ST_AlgorithmType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"composite\"/>\n      <xsd:enumeration value=\"conn\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"hierChild\"/>\n      <xsd:enumeration value=\"hierRoot\"/>\n      <xsd:enumeration value=\"pyra\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"snake\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n      <xsd:enumeration value=\"desOrSelf\"/>\n      <xsd:enumeration value=\"par\"/>\n      <xsd:enumeration value=\"ancst\"/>\n      <xsd:enumeration value=\"ancstOrSelf\"/>\n      <xsd:enumeration value=\"followSib\"/>\n      <xsd:enumeration value=\"precedSib\"/>\n      <xsd:enumeration value=\"follow\"/>\n      <xsd:enumeration value=\"preced\"/>\n      <xsd:enumeration value=\"root\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AxisTypes\">\n    <xsd:list itemType=\"ST_AxisType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BoolOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildOrderType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"t\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alignOff\"/>\n      <xsd:enumeration value=\"begMarg\"/>\n      <xsd:enumeration value=\"bendDist\"/>\n      <xsd:enumeration value=\"begPad\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"bMarg\"/>\n      <xsd:enumeration value=\"bOff\"/>\n      <xsd:enumeration value=\"ctrX\"/>\n      <xsd:enumeration value=\"ctrXOff\"/>\n      <xsd:enumeration value=\"ctrY\"/>\n      <xsd:enumeration value=\"ctrYOff\"/>\n      <xsd:enumeration value=\"connDist\"/>\n      <xsd:enumeration value=\"diam\"/>\n      <xsd:enumeration value=\"endMarg\"/>\n      <xsd:enumeration value=\"endPad\"/>\n      <xsd:enumeration value=\"h\"/>\n      <xsd:enumeration value=\"hArH\"/>\n      <xsd:enumeration value=\"hOff\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"lMarg\"/>\n      <xsd:enumeration value=\"lOff\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"rMarg\"/>\n      <xsd:enumeration value=\"rOff\"/>\n      <xsd:enumeration value=\"primFontSz\"/>\n      <xsd:enumeration value=\"pyraAcctRatio\"/>\n      <xsd:enumeration value=\"secFontSz\"/>\n      <xsd:enumeration value=\"sibSp\"/>\n      <xsd:enumeration value=\"secSibSp\"/>\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"stemThick\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tMarg\"/>\n      <xsd:enumeration value=\"tOff\"/>\n      <xsd:enumeration value=\"userA\"/>\n      <xsd:enumeration value=\"userB\"/>\n      <xsd:enumeration value=\"userC\"/>\n      <xsd:enumeration value=\"userD\"/>\n      <xsd:enumeration value=\"userE\"/>\n      <xsd:enumeration value=\"userF\"/>\n      <xsd:enumeration value=\"userG\"/>\n      <xsd:enumeration value=\"userH\"/>\n      <xsd:enumeration value=\"userI\"/>\n      <xsd:enumeration value=\"userJ\"/>\n      <xsd:enumeration value=\"userK\"/>\n      <xsd:enumeration value=\"userL\"/>\n      <xsd:enumeration value=\"userM\"/>\n      <xsd:enumeration value=\"userN\"/>\n      <xsd:enumeration value=\"userO\"/>\n      <xsd:enumeration value=\"userP\"/>\n      <xsd:enumeration value=\"userQ\"/>\n      <xsd:enumeration value=\"userR\"/>\n      <xsd:enumeration value=\"userS\"/>\n      <xsd:enumeration value=\"userT\"/>\n      <xsd:enumeration value=\"userU\"/>\n      <xsd:enumeration value=\"userV\"/>\n      <xsd:enumeration value=\"userW\"/>\n      <xsd:enumeration value=\"userX\"/>\n      <xsd:enumeration value=\"userY\"/>\n      <xsd:enumeration value=\"userZ\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"wArH\"/>\n      <xsd:enumeration value=\"wOff\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConstraintRelationship\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"self\"/>\n      <xsd:enumeration value=\"ch\"/>\n      <xsd:enumeration value=\"des\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"doc\"/>\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"nonNorm\"/>\n      <xsd:enumeration value=\"asst\"/>\n      <xsd:enumeration value=\"nonAsst\"/>\n      <xsd:enumeration value=\"parTrans\"/>\n      <xsd:enumeration value=\"pres\"/>\n      <xsd:enumeration value=\"sibTrans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ElementTypes\">\n    <xsd:list itemType=\"ST_ElementType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ParameterId\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horzAlign\"/>\n      <xsd:enumeration value=\"vertAlign\"/>\n      <xsd:enumeration value=\"chDir\"/>\n      <xsd:enumeration value=\"chAlign\"/>\n      <xsd:enumeration value=\"secChAlign\"/>\n      <xsd:enumeration value=\"linDir\"/>\n      <xsd:enumeration value=\"secLinDir\"/>\n      <xsd:enumeration value=\"stElem\"/>\n      <xsd:enumeration value=\"bendPt\"/>\n      <xsd:enumeration value=\"connRout\"/>\n      <xsd:enumeration value=\"begSty\"/>\n      <xsd:enumeration value=\"endSty\"/>\n      <xsd:enumeration value=\"dim\"/>\n      <xsd:enumeration value=\"rotPath\"/>\n      <xsd:enumeration value=\"ctrShpMap\"/>\n      <xsd:enumeration value=\"nodeHorzAlign\"/>\n      <xsd:enumeration value=\"nodeVertAlign\"/>\n      <xsd:enumeration value=\"fallback\"/>\n      <xsd:enumeration value=\"txDir\"/>\n      <xsd:enumeration value=\"pyraAcctPos\"/>\n      <xsd:enumeration value=\"pyraAcctTxMar\"/>\n      <xsd:enumeration value=\"txBlDir\"/>\n      <xsd:enumeration value=\"txAnchorHorz\"/>\n      <xsd:enumeration value=\"txAnchorVert\"/>\n      <xsd:enumeration value=\"txAnchorHorzCh\"/>\n      <xsd:enumeration value=\"txAnchorVertCh\"/>\n      <xsd:enumeration value=\"parTxLTRAlign\"/>\n      <xsd:enumeration value=\"parTxRTLAlign\"/>\n      <xsd:enumeration value=\"shpTxLTRAlignCh\"/>\n      <xsd:enumeration value=\"shpTxRTLAlignCh\"/>\n      <xsd:enumeration value=\"autoTxRot\"/>\n      <xsd:enumeration value=\"grDir\"/>\n      <xsd:enumeration value=\"flowDir\"/>\n      <xsd:enumeration value=\"contDir\"/>\n      <xsd:enumeration value=\"bkpt\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"hierAlign\"/>\n      <xsd:enumeration value=\"bkPtFixedVal\"/>\n      <xsd:enumeration value=\"stBulletLvl\"/>\n      <xsd:enumeration value=\"stAng\"/>\n      <xsd:enumeration value=\"spanAng\"/>\n      <xsd:enumeration value=\"ar\"/>\n      <xsd:enumeration value=\"lnSpPar\"/>\n      <xsd:enumeration value=\"lnSpAfParP\"/>\n      <xsd:enumeration value=\"lnSpCh\"/>\n      <xsd:enumeration value=\"lnSpAfChP\"/>\n      <xsd:enumeration value=\"rtShortDist\"/>\n      <xsd:enumeration value=\"alignTx\"/>\n      <xsd:enumeration value=\"pyraLvlNode\"/>\n      <xsd:enumeration value=\"pyraAcctBkgdNode\"/>\n      <xsd:enumeration value=\"pyraAcctTxNode\"/>\n      <xsd:enumeration value=\"srcNode\"/>\n      <xsd:enumeration value=\"dstNode\"/>\n      <xsd:enumeration value=\"begPts\"/>\n      <xsd:enumeration value=\"endPts\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ints\">\n    <xsd:list itemType=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedInts\">\n    <xsd:list itemType=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Booleans\">\n    <xsd:list itemType=\"xsd:boolean\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cnt\"/>\n      <xsd:enumeration value=\"pos\"/>\n      <xsd:enumeration value=\"revPos\"/>\n      <xsd:enumeration value=\"posEven\"/>\n      <xsd:enumeration value=\"posOdd\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"depth\"/>\n      <xsd:enumeration value=\"maxDepth\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionOperator\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"equ\"/>\n      <xsd:enumeration value=\"neq\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"gte\"/>\n      <xsd:enumeration value=\"lte\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryChildAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SecondaryLinearDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fromL\"/>\n      <xsd:enumeration value=\"fromR\"/>\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StartingElement\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"node\"/>\n      <xsd:enumeration value=\"trans\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RotationPath\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"alongPath\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CenterShapeMapping\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fNode\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BendPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"beg\"/>\n      <xsd:enumeration value=\"def\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorRouting\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"stra\"/>\n      <xsd:enumeration value=\"bend\"/>\n      <xsd:enumeration value=\"curve\"/>\n      <xsd:enumeration value=\"longCurve\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrowheadStyle\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"arr\"/>\n      <xsd:enumeration value=\"noArr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorPoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"bCtr\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"midL\"/>\n      <xsd:enumeration value=\"midR\"/>\n      <xsd:enumeration value=\"tCtr\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"radial\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeHorizontalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_NodeVerticalAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FallbackDimension\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"1D\"/>\n      <xsd:enumeration value=\"2D\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fromT\"/>\n      <xsd:enumeration value=\"fromB\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentPosition\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bef\"/>\n      <xsd:enumeration value=\"aft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PyramidAccentTextMargin\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"step\"/>\n      <xsd:enumeration value=\"stack\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBlockDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorHorizontal\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ctr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAnchorVertical\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"mid\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramTextAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AutoTextRotation\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"upr\"/>\n      <xsd:enumeration value=\"grav\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GrowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FlowDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"col\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContinueDirection\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"revDir\"/>\n      <xsd:enumeration value=\"sameDir\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Breakpoint\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"endCnv\"/>\n      <xsd:enumeration value=\"bal\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Offset\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HierarchyAlignment\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tL\"/>\n      <xsd:enumeration value=\"tR\"/>\n      <xsd:enumeration value=\"tCtrCh\"/>\n      <xsd:enumeration value=\"tCtrDes\"/>\n      <xsd:enumeration value=\"bL\"/>\n      <xsd:enumeration value=\"bR\"/>\n      <xsd:enumeration value=\"bCtrCh\"/>\n      <xsd:enumeration value=\"bCtrDes\"/>\n      <xsd:enumeration value=\"lT\"/>\n      <xsd:enumeration value=\"lB\"/>\n      <xsd:enumeration value=\"lCtrCh\"/>\n      <xsd:enumeration value=\"lCtrDes\"/>\n      <xsd:enumeration value=\"rT\"/>\n      <xsd:enumeration value=\"rB\"/>\n      <xsd:enumeration value=\"rCtrCh\"/>\n      <xsd:enumeration value=\"rCtrDes\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionValue\" final=\"restriction\">\n    <xsd:union\n      memberTypes=\"xsd:int xsd:boolean ST_Direction ST_HierBranchStyle ST_AnimOneStr ST_AnimLvlStr ST_ResizeHandlesStr\"\n    />\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VariableType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"orgChart\"/>\n      <xsd:enumeration value=\"chMax\"/>\n      <xsd:enumeration value=\"chPref\"/>\n      <xsd:enumeration value=\"bulEnabled\"/>\n      <xsd:enumeration value=\"dir\"/>\n      <xsd:enumeration value=\"hierBranch\"/>\n      <xsd:enumeration value=\"animOne\"/>\n      <xsd:enumeration value=\"animLvl\"/>\n      <xsd:enumeration value=\"resizeHandles\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FunctionArgument\" final=\"restriction\">\n    <xsd:union memberTypes=\"ST_VariableType\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OutputShapeType\" final=\"restriction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"conn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:element name=\"lockedCanvas\" type=\"a:CT_GvmlGroupShape\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/diagram\"\n    schemaLocation=\"dml-diagram.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/chart\"\n    schemaLocation=\"dml-chart.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas\"\n    schemaLocation=\"dml-lockedCanvas.xsd\"/>\n  <xsd:complexType name=\"CT_AudioFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VideoFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n    <xsd:attribute name=\"contentType\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QuickTimeFile\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:link\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCDTime\">\n    <xsd:attribute name=\"track\" type=\"xsd:unsignedByte\" use=\"required\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AudioCD\">\n    <xsd:sequence>\n      <xsd:element name=\"st\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_AudioCDTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Media\">\n    <xsd:choice>\n      <xsd:element name=\"audioCd\" type=\"CT_AudioCD\"/>\n      <xsd:element name=\"wavAudioFile\" type=\"CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"audioFile\" type=\"CT_AudioFile\"/>\n      <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n      <xsd:element name=\"quickTimeFile\" type=\"CT_QuickTimeFile\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"videoFile\" type=\"CT_VideoFile\"/>\n  <xsd:simpleType name=\"ST_StyleMatrixColumnIndex\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontCollectionIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"dk1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dk2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lt2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent1\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent2\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent3\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent4\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent5\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"accent6\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"folHlink\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SupplementalFont\">\n    <xsd:attribute name=\"script\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomColorList\">\n    <xsd:sequence>\n      <xsd:element name=\"custClr\" type=\"CT_CustomColor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontCollection\">\n    <xsd:sequence>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"font\" type=\"CT_SupplementalFont\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleItem\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:sequence>\n      <xsd:element name=\"majorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"minorFont\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LineStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"effectStyle\" type=\"CT_EffectStyleItem\" minOccurs=\"3\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFillStyleList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"3\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrix\">\n    <xsd:sequence>\n      <xsd:element name=\"fillStyleLst\" type=\"CT_FillStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnStyleLst\" type=\"CT_LineStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectStyleLst\" type=\"CT_EffectStyleList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgFillStyleLst\" type=\"CT_BackgroundFillStyleList\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeArtExtension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Coordinate\">\n    <xsd:union memberTypes=\"ST_CoordinateUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CoordinateUnqualified\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"-27273042329600\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32\">\n    <xsd:union memberTypes=\"ST_Coordinate32Unqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Coordinate32Unqualified\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate\">\n    <xsd:restriction base=\"xsd:long\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"27273042316900\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveCoordinate32\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Angle\">\n    <xsd:attribute name=\"val\" type=\"ST_Angle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minExclusive value=\"-5400000\"/>\n      <xsd:maxExclusive value=\"5400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxExclusive value=\"21600000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedAngle\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:union memberTypes=\"ST_PercentageDecimal s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PercentageDecimal\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Percentage\">\n    <xsd:attribute name=\"val\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:union memberTypes=\"ST_PositivePercentageDecimal s:ST_PositivePercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositivePercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:union memberTypes=\"ST_FixedPercentageDecimal s:ST_FixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"-100000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:union memberTypes=\"ST_PositiveFixedPercentageDecimal s:ST_PositiveFixedPercentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentageDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n    <xsd:attribute name=\"val\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ratio\">\n    <xsd:attribute name=\"n\" type=\"xsd:long\" use=\"required\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:long\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point2D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PositiveSize2D\">\n    <xsd:attribute name=\"cx\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ComplementTransform\"/>\n  <xsd:complexType name=\"CT_InverseTransform\"/>\n  <xsd:complexType name=\"CT_GrayscaleTransform\"/>\n  <xsd:complexType name=\"CT_GammaTransform\"/>\n  <xsd:complexType name=\"CT_InverseGammaTransform\"/>\n  <xsd:group name=\"EG_ColorTransform\">\n    <xsd:choice>\n      <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"comp\" type=\"CT_ComplementTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"inv\" type=\"CT_InverseTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gray\" type=\"CT_GrayscaleTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOff\" type=\"CT_FixedPercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hue\" type=\"CT_PositiveFixedAngle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueOff\" type=\"CT_Angle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sat\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"satMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lumMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"red\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"redMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"green\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"greenMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blue\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueOff\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blueMod\" type=\"CT_Percentage\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gamma\" type=\"CT_GammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"invGamma\" type=\"CT_InverseGammaTransform\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ScRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SRgbColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HslColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SystemColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"scrollBar\"/>\n      <xsd:enumeration value=\"background\"/>\n      <xsd:enumeration value=\"activeCaption\"/>\n      <xsd:enumeration value=\"inactiveCaption\"/>\n      <xsd:enumeration value=\"menu\"/>\n      <xsd:enumeration value=\"window\"/>\n      <xsd:enumeration value=\"windowFrame\"/>\n      <xsd:enumeration value=\"menuText\"/>\n      <xsd:enumeration value=\"windowText\"/>\n      <xsd:enumeration value=\"captionText\"/>\n      <xsd:enumeration value=\"activeBorder\"/>\n      <xsd:enumeration value=\"inactiveBorder\"/>\n      <xsd:enumeration value=\"appWorkspace\"/>\n      <xsd:enumeration value=\"highlight\"/>\n      <xsd:enumeration value=\"highlightText\"/>\n      <xsd:enumeration value=\"btnFace\"/>\n      <xsd:enumeration value=\"btnShadow\"/>\n      <xsd:enumeration value=\"grayText\"/>\n      <xsd:enumeration value=\"btnText\"/>\n      <xsd:enumeration value=\"inactiveCaptionText\"/>\n      <xsd:enumeration value=\"btnHighlight\"/>\n      <xsd:enumeration value=\"3dDkShadow\"/>\n      <xsd:enumeration value=\"3dLight\"/>\n      <xsd:enumeration value=\"infoText\"/>\n      <xsd:enumeration value=\"infoBk\"/>\n      <xsd:enumeration value=\"hotLight\"/>\n      <xsd:enumeration value=\"gradientActiveCaption\"/>\n      <xsd:enumeration value=\"gradientInactiveCaption\"/>\n      <xsd:enumeration value=\"menuHighlight\"/>\n      <xsd:enumeration value=\"menuBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SystemColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SystemColorVal\" use=\"required\"/>\n    <xsd:attribute name=\"lastClr\" type=\"s:ST_HexColorRGB\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SchemeColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bg1\"/>\n      <xsd:enumeration value=\"tx1\"/>\n      <xsd:enumeration value=\"bg2\"/>\n      <xsd:enumeration value=\"tx2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hlink\"/>\n      <xsd:enumeration value=\"folHlink\"/>\n      <xsd:enumeration value=\"phClr\"/>\n      <xsd:enumeration value=\"dk1\"/>\n      <xsd:enumeration value=\"lt1\"/>\n      <xsd:enumeration value=\"dk2\"/>\n      <xsd:enumeration value=\"lt2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SchemeColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetColorVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"aliceBlue\"/>\n      <xsd:enumeration value=\"antiqueWhite\"/>\n      <xsd:enumeration value=\"aqua\"/>\n      <xsd:enumeration value=\"aquamarine\"/>\n      <xsd:enumeration value=\"azure\"/>\n      <xsd:enumeration value=\"beige\"/>\n      <xsd:enumeration value=\"bisque\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blanchedAlmond\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"blueViolet\"/>\n      <xsd:enumeration value=\"brown\"/>\n      <xsd:enumeration value=\"burlyWood\"/>\n      <xsd:enumeration value=\"cadetBlue\"/>\n      <xsd:enumeration value=\"chartreuse\"/>\n      <xsd:enumeration value=\"chocolate\"/>\n      <xsd:enumeration value=\"coral\"/>\n      <xsd:enumeration value=\"cornflowerBlue\"/>\n      <xsd:enumeration value=\"cornsilk\"/>\n      <xsd:enumeration value=\"crimson\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGoldenrod\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"darkGrey\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkKhaki\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkOliveGreen\"/>\n      <xsd:enumeration value=\"darkOrange\"/>\n      <xsd:enumeration value=\"darkOrchid\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkSalmon\"/>\n      <xsd:enumeration value=\"darkSeaGreen\"/>\n      <xsd:enumeration value=\"darkSlateBlue\"/>\n      <xsd:enumeration value=\"darkSlateGray\"/>\n      <xsd:enumeration value=\"darkSlateGrey\"/>\n      <xsd:enumeration value=\"darkTurquoise\"/>\n      <xsd:enumeration value=\"darkViolet\"/>\n      <xsd:enumeration value=\"dkBlue\"/>\n      <xsd:enumeration value=\"dkCyan\"/>\n      <xsd:enumeration value=\"dkGoldenrod\"/>\n      <xsd:enumeration value=\"dkGray\"/>\n      <xsd:enumeration value=\"dkGrey\"/>\n      <xsd:enumeration value=\"dkGreen\"/>\n      <xsd:enumeration value=\"dkKhaki\"/>\n      <xsd:enumeration value=\"dkMagenta\"/>\n      <xsd:enumeration value=\"dkOliveGreen\"/>\n      <xsd:enumeration value=\"dkOrange\"/>\n      <xsd:enumeration value=\"dkOrchid\"/>\n      <xsd:enumeration value=\"dkRed\"/>\n      <xsd:enumeration value=\"dkSalmon\"/>\n      <xsd:enumeration value=\"dkSeaGreen\"/>\n      <xsd:enumeration value=\"dkSlateBlue\"/>\n      <xsd:enumeration value=\"dkSlateGray\"/>\n      <xsd:enumeration value=\"dkSlateGrey\"/>\n      <xsd:enumeration value=\"dkTurquoise\"/>\n      <xsd:enumeration value=\"dkViolet\"/>\n      <xsd:enumeration value=\"deepPink\"/>\n      <xsd:enumeration value=\"deepSkyBlue\"/>\n      <xsd:enumeration value=\"dimGray\"/>\n      <xsd:enumeration value=\"dimGrey\"/>\n      <xsd:enumeration value=\"dodgerBlue\"/>\n      <xsd:enumeration value=\"firebrick\"/>\n      <xsd:enumeration value=\"floralWhite\"/>\n      <xsd:enumeration value=\"forestGreen\"/>\n      <xsd:enumeration value=\"fuchsia\"/>\n      <xsd:enumeration value=\"gainsboro\"/>\n      <xsd:enumeration value=\"ghostWhite\"/>\n      <xsd:enumeration value=\"gold\"/>\n      <xsd:enumeration value=\"goldenrod\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"grey\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"greenYellow\"/>\n      <xsd:enumeration value=\"honeydew\"/>\n      <xsd:enumeration value=\"hotPink\"/>\n      <xsd:enumeration value=\"indianRed\"/>\n      <xsd:enumeration value=\"indigo\"/>\n      <xsd:enumeration value=\"ivory\"/>\n      <xsd:enumeration value=\"khaki\"/>\n      <xsd:enumeration value=\"lavender\"/>\n      <xsd:enumeration value=\"lavenderBlush\"/>\n      <xsd:enumeration value=\"lawnGreen\"/>\n      <xsd:enumeration value=\"lemonChiffon\"/>\n      <xsd:enumeration value=\"lightBlue\"/>\n      <xsd:enumeration value=\"lightCoral\"/>\n      <xsd:enumeration value=\"lightCyan\"/>\n      <xsd:enumeration value=\"lightGoldenrodYellow\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"lightGrey\"/>\n      <xsd:enumeration value=\"lightGreen\"/>\n      <xsd:enumeration value=\"lightPink\"/>\n      <xsd:enumeration value=\"lightSalmon\"/>\n      <xsd:enumeration value=\"lightSeaGreen\"/>\n      <xsd:enumeration value=\"lightSkyBlue\"/>\n      <xsd:enumeration value=\"lightSlateGray\"/>\n      <xsd:enumeration value=\"lightSlateGrey\"/>\n      <xsd:enumeration value=\"lightSteelBlue\"/>\n      <xsd:enumeration value=\"lightYellow\"/>\n      <xsd:enumeration value=\"ltBlue\"/>\n      <xsd:enumeration value=\"ltCoral\"/>\n      <xsd:enumeration value=\"ltCyan\"/>\n      <xsd:enumeration value=\"ltGoldenrodYellow\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"ltGrey\"/>\n      <xsd:enumeration value=\"ltGreen\"/>\n      <xsd:enumeration value=\"ltPink\"/>\n      <xsd:enumeration value=\"ltSalmon\"/>\n      <xsd:enumeration value=\"ltSeaGreen\"/>\n      <xsd:enumeration value=\"ltSkyBlue\"/>\n      <xsd:enumeration value=\"ltSlateGray\"/>\n      <xsd:enumeration value=\"ltSlateGrey\"/>\n      <xsd:enumeration value=\"ltSteelBlue\"/>\n      <xsd:enumeration value=\"ltYellow\"/>\n      <xsd:enumeration value=\"lime\"/>\n      <xsd:enumeration value=\"limeGreen\"/>\n      <xsd:enumeration value=\"linen\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"maroon\"/>\n      <xsd:enumeration value=\"medAquamarine\"/>\n      <xsd:enumeration value=\"medBlue\"/>\n      <xsd:enumeration value=\"medOrchid\"/>\n      <xsd:enumeration value=\"medPurple\"/>\n      <xsd:enumeration value=\"medSeaGreen\"/>\n      <xsd:enumeration value=\"medSlateBlue\"/>\n      <xsd:enumeration value=\"medSpringGreen\"/>\n      <xsd:enumeration value=\"medTurquoise\"/>\n      <xsd:enumeration value=\"medVioletRed\"/>\n      <xsd:enumeration value=\"mediumAquamarine\"/>\n      <xsd:enumeration value=\"mediumBlue\"/>\n      <xsd:enumeration value=\"mediumOrchid\"/>\n      <xsd:enumeration value=\"mediumPurple\"/>\n      <xsd:enumeration value=\"mediumSeaGreen\"/>\n      <xsd:enumeration value=\"mediumSlateBlue\"/>\n      <xsd:enumeration value=\"mediumSpringGreen\"/>\n      <xsd:enumeration value=\"mediumTurquoise\"/>\n      <xsd:enumeration value=\"mediumVioletRed\"/>\n      <xsd:enumeration value=\"midnightBlue\"/>\n      <xsd:enumeration value=\"mintCream\"/>\n      <xsd:enumeration value=\"mistyRose\"/>\n      <xsd:enumeration value=\"moccasin\"/>\n      <xsd:enumeration value=\"navajoWhite\"/>\n      <xsd:enumeration value=\"navy\"/>\n      <xsd:enumeration value=\"oldLace\"/>\n      <xsd:enumeration value=\"olive\"/>\n      <xsd:enumeration value=\"oliveDrab\"/>\n      <xsd:enumeration value=\"orange\"/>\n      <xsd:enumeration value=\"orangeRed\"/>\n      <xsd:enumeration value=\"orchid\"/>\n      <xsd:enumeration value=\"paleGoldenrod\"/>\n      <xsd:enumeration value=\"paleGreen\"/>\n      <xsd:enumeration value=\"paleTurquoise\"/>\n      <xsd:enumeration value=\"paleVioletRed\"/>\n      <xsd:enumeration value=\"papayaWhip\"/>\n      <xsd:enumeration value=\"peachPuff\"/>\n      <xsd:enumeration value=\"peru\"/>\n      <xsd:enumeration value=\"pink\"/>\n      <xsd:enumeration value=\"plum\"/>\n      <xsd:enumeration value=\"powderBlue\"/>\n      <xsd:enumeration value=\"purple\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"rosyBrown\"/>\n      <xsd:enumeration value=\"royalBlue\"/>\n      <xsd:enumeration value=\"saddleBrown\"/>\n      <xsd:enumeration value=\"salmon\"/>\n      <xsd:enumeration value=\"sandyBrown\"/>\n      <xsd:enumeration value=\"seaGreen\"/>\n      <xsd:enumeration value=\"seaShell\"/>\n      <xsd:enumeration value=\"sienna\"/>\n      <xsd:enumeration value=\"silver\"/>\n      <xsd:enumeration value=\"skyBlue\"/>\n      <xsd:enumeration value=\"slateBlue\"/>\n      <xsd:enumeration value=\"slateGray\"/>\n      <xsd:enumeration value=\"slateGrey\"/>\n      <xsd:enumeration value=\"snow\"/>\n      <xsd:enumeration value=\"springGreen\"/>\n      <xsd:enumeration value=\"steelBlue\"/>\n      <xsd:enumeration value=\"tan\"/>\n      <xsd:enumeration value=\"teal\"/>\n      <xsd:enumeration value=\"thistle\"/>\n      <xsd:enumeration value=\"tomato\"/>\n      <xsd:enumeration value=\"turquoise\"/>\n      <xsd:enumeration value=\"violet\"/>\n      <xsd:enumeration value=\"wheat\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"whiteSmoke\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"yellowGreen\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetColor\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"val\" type=\"ST_PresetColorVal\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_OfficeArtExtension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OfficeArtExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OfficeArtExtensionList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scale2D\">\n    <xsd:sequence>\n      <xsd:element name=\"sx\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sy\" type=\"CT_Ratio\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Transform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupTransform2D\">\n    <xsd:sequence>\n      <xsd:element name=\"off\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ext\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chOff\" type=\"CT_Point2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"chExt\" type=\"CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"flipH\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"flipV\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Point3D\">\n    <xsd:attribute name=\"x\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vector3D\">\n    <xsd:attribute name=\"dx\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dy\" type=\"ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"dz\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SphereCoords\">\n    <xsd:attribute name=\"lat\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"lon\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n    <xsd:attribute name=\"rev\" type=\"ST_PositiveFixedAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeRect\">\n    <xsd:attribute name=\"l\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"t\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"r\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"b\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RectAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:group name=\"EG_ColorChoice\">\n    <xsd:choice>\n      <xsd:element name=\"scrgbClr\" type=\"CT_ScRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hslClr\" type=\"CT_HslColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sysClr\" type=\"CT_SystemColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstClr\" type=\"CT_PresetColor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMRU\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlackWhiteMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clr\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"ltGray\"/>\n      <xsd:enumeration value=\"invGray\"/>\n      <xsd:enumeration value=\"grayWhite\"/>\n      <xsd:enumeration value=\"blackGray\"/>\n      <xsd:enumeration value=\"blackWhite\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Blob\">\n    <xsd:attribute ref=\"r:embed\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:link\" use=\"optional\" default=\"\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_EmbeddedWAVAudioFile\">\n    <xsd:attribute ref=\"r:embed\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:sequence>\n      <xsd:element name=\"snd\" type=\"CT_EmbeddedWAVAudioFile\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalidUrl\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"action\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"tooltip\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"highlightClick\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"endSnd\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DrawingElementId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Locking\">\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noEditPoints\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noAdjustHandles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeArrowheads\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeShapeType\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_ConnectorLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noTextEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n    <xsd:attribute name=\"noCrop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noUngrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noRot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"noGrp\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noDrilldown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noSelect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noChangeAspect\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noMove\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"noResize\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ContentPartLocking\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Locking\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkHover\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"descr\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"spLocks\" type=\"CT_ShapeLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"txBox\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualConnectorProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cxnSpLocks\" type=\"CT_ConnectorLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCxn\" type=\"CT_Connection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualPictureProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"picLocks\" type=\"CT_PictureLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preferRelativeResize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGroupDrawingShapeProps\">\n    <xsd:sequence>\n      <xsd:element name=\"grpSpLocks\" type=\"CT_GroupLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualGraphicFrameProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicFrameLocks\" type=\"CT_GraphicalObjectFrameLocking\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NonVisualContentPartProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cpLocks\" type=\"CT_ContentPartLocking\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isComment\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectData\">\n    <xsd:sequence>\n      <xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"strict\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObject\">\n    <xsd:sequence>\n      <xsd:element name=\"graphicData\" type=\"CT_GraphicalObjectData\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"graphic\" type=\"CT_GraphicalObject\"/>\n  <xsd:simpleType name=\"ST_ChartBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"allPts\"/>\n      <xsd:enumeration value=\"gridLegend\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DgmBuildStep\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sp\"/>\n      <xsd:enumeration value=\"bg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmElement\">\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"optional\"\n      default=\"{00000000-0000-0000-0000-000000000000}\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_DgmBuildStep\" use=\"optional\" default=\"sp\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationChartElement\">\n    <xsd:attribute name=\"seriesIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"categoryIdx\" type=\"xsd:int\" use=\"optional\" default=\"-1\"/>\n    <xsd:attribute name=\"bldStep\" type=\"ST_ChartBuildStep\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationElementChoice\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"dgm\" type=\"CT_AnimationDgmElement\"/>\n      <xsd:element name=\"chart\" type=\"CT_AnimationChartElement\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"one\"/>\n      <xsd:enumeration value=\"lvlOne\"/>\n      <xsd:enumeration value=\"lvlAtOnce\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationDgmBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationDgmOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationDgmBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationDgmBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AnimationChartOnlyBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnimationChartBuildType\">\n    <xsd:union memberTypes=\"ST_AnimationBuildType ST_AnimationChartOnlyBuildType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AnimationChartBuildProperties\">\n    <xsd:attribute name=\"bld\" type=\"ST_AnimationChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AnimationGraphicalObjectBuildProperties\">\n    <xsd:choice>\n      <xsd:element name=\"bldDgm\" type=\"CT_AnimationDgmBuildProperties\"/>\n      <xsd:element name=\"bldChart\" type=\"CT_AnimationChartBuildProperties\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BackgroundFormatting\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WholeE2oFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlUseShapeRectangle\"/>\n  <xsd:complexType name=\"CT_GvmlTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"useSpRect\" type=\"CT_GvmlUseShapeRectangle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_GvmlShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlConnector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_GvmlConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"CT_NonVisualPictureProperties\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlPicture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_GvmlPictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GvmlGraphicFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element ref=\"graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GvmlGroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GvmlGroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"txSp\" type=\"CT_GvmlTextShape\"/>\n        <xsd:element name=\"sp\" type=\"CT_GvmlShape\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_GvmlConnector\"/>\n        <xsd:element name=\"pic\" type=\"CT_GvmlPicture\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GvmlGraphicalObjectFrame\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GvmlGroupShape\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetCameraType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueTop\"/>\n      <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n      <xsd:enumeration value=\"legacyObliqueLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueFront\"/>\n      <xsd:enumeration value=\"legacyObliqueRight\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n      <xsd:enumeration value=\"legacyObliqueBottom\"/>\n      <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n      <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n      <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n      <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n      <xsd:enumeration value=\"orthographicFront\"/>\n      <xsd:enumeration value=\"isometricTopUp\"/>\n      <xsd:enumeration value=\"isometricTopDown\"/>\n      <xsd:enumeration value=\"isometricBottomUp\"/>\n      <xsd:enumeration value=\"isometricBottomDown\"/>\n      <xsd:enumeration value=\"isometricLeftUp\"/>\n      <xsd:enumeration value=\"isometricLeftDown\"/>\n      <xsd:enumeration value=\"isometricRightUp\"/>\n      <xsd:enumeration value=\"isometricRightDown\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n      <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n      <xsd:enumeration value=\"obliqueTopLeft\"/>\n      <xsd:enumeration value=\"obliqueTop\"/>\n      <xsd:enumeration value=\"obliqueTopRight\"/>\n      <xsd:enumeration value=\"obliqueLeft\"/>\n      <xsd:enumeration value=\"obliqueRight\"/>\n      <xsd:enumeration value=\"obliqueBottomLeft\"/>\n      <xsd:enumeration value=\"obliqueBottom\"/>\n      <xsd:enumeration value=\"obliqueBottomRight\"/>\n      <xsd:enumeration value=\"perspectiveFront\"/>\n      <xsd:enumeration value=\"perspectiveLeft\"/>\n      <xsd:enumeration value=\"perspectiveRight\"/>\n      <xsd:enumeration value=\"perspectiveAbove\"/>\n      <xsd:enumeration value=\"perspectiveBelow\"/>\n      <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n      <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n      <xsd:enumeration value=\"perspectiveRelaxed\"/>\n      <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FOVAngle\">\n    <xsd:restriction base=\"ST_Angle\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"10800000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Camera\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetCameraType\" use=\"required\"/>\n    <xsd:attribute name=\"fov\" type=\"ST_FOVAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"zoom\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LightRigDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"tl\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"tr\"/>\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"bl\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"br\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LightRigType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyFlat1\"/>\n      <xsd:enumeration value=\"legacyFlat2\"/>\n      <xsd:enumeration value=\"legacyFlat3\"/>\n      <xsd:enumeration value=\"legacyFlat4\"/>\n      <xsd:enumeration value=\"legacyNormal1\"/>\n      <xsd:enumeration value=\"legacyNormal2\"/>\n      <xsd:enumeration value=\"legacyNormal3\"/>\n      <xsd:enumeration value=\"legacyNormal4\"/>\n      <xsd:enumeration value=\"legacyHarsh1\"/>\n      <xsd:enumeration value=\"legacyHarsh2\"/>\n      <xsd:enumeration value=\"legacyHarsh3\"/>\n      <xsd:enumeration value=\"legacyHarsh4\"/>\n      <xsd:enumeration value=\"threePt\"/>\n      <xsd:enumeration value=\"balanced\"/>\n      <xsd:enumeration value=\"soft\"/>\n      <xsd:enumeration value=\"harsh\"/>\n      <xsd:enumeration value=\"flood\"/>\n      <xsd:enumeration value=\"contrasting\"/>\n      <xsd:enumeration value=\"morning\"/>\n      <xsd:enumeration value=\"sunrise\"/>\n      <xsd:enumeration value=\"sunset\"/>\n      <xsd:enumeration value=\"chilly\"/>\n      <xsd:enumeration value=\"freezing\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"twoPt\"/>\n      <xsd:enumeration value=\"glow\"/>\n      <xsd:enumeration value=\"brightRoom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LightRig\">\n    <xsd:sequence>\n      <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scene3D\">\n    <xsd:sequence>\n      <xsd:element name=\"camera\" type=\"CT_Camera\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"backdrop\" type=\"CT_Backdrop\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Backdrop\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_Point3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"norm\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"up\" type=\"CT_Vector3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BevelPresetType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relaxedInset\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"slope\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"softRound\"/>\n      <xsd:enumeration value=\"convex\"/>\n      <xsd:enumeration value=\"coolSlant\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"riblet\"/>\n      <xsd:enumeration value=\"hardEdge\"/>\n      <xsd:enumeration value=\"artDeco\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Bevel\">\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"76200\"/>\n    <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\" default=\"circle\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetMaterialType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"legacyMatte\"/>\n      <xsd:enumeration value=\"legacyPlastic\"/>\n      <xsd:enumeration value=\"legacyMetal\"/>\n      <xsd:enumeration value=\"legacyWireframe\"/>\n      <xsd:enumeration value=\"matte\"/>\n      <xsd:enumeration value=\"plastic\"/>\n      <xsd:enumeration value=\"metal\"/>\n      <xsd:enumeration value=\"warmMatte\"/>\n      <xsd:enumeration value=\"translucentPowder\"/>\n      <xsd:enumeration value=\"powder\"/>\n      <xsd:enumeration value=\"dkEdge\"/>\n      <xsd:enumeration value=\"softEdge\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"softmetal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shape3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"extrusionH\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"contourW\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"\n      default=\"warmMatte\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FlatText\">\n    <xsd:attribute name=\"z\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Text3D\">\n    <xsd:choice>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"flatTx\" type=\"CT_FlatText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AlphaBiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaCeilingEffect\"/>\n  <xsd:complexType name=\"CT_AlphaFloorEffect\"/>\n  <xsd:complexType name=\"CT_AlphaInverseEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateFixedEffect\">\n    <xsd:attribute name=\"amt\" type=\"ST_PositivePercentage\" use=\"optional\" default=\"100%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaOutsetEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaReplaceEffect\">\n    <xsd:attribute name=\"a\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BiLevelEffect\">\n    <xsd:attribute name=\"thresh\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlurEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"grow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorChangeEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"clrFrom\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrTo\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useA\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorReplaceEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DuotoneEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GrayscaleEffect\"/>\n  <xsd:complexType name=\"CT_HSLEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sat\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"lum\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InnerShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LuminanceEffect\">\n    <xsd:attribute name=\"bright\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"contrast\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OuterShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetShadowVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shdw1\"/>\n      <xsd:enumeration value=\"shdw2\"/>\n      <xsd:enumeration value=\"shdw3\"/>\n      <xsd:enumeration value=\"shdw4\"/>\n      <xsd:enumeration value=\"shdw5\"/>\n      <xsd:enumeration value=\"shdw6\"/>\n      <xsd:enumeration value=\"shdw7\"/>\n      <xsd:enumeration value=\"shdw8\"/>\n      <xsd:enumeration value=\"shdw9\"/>\n      <xsd:enumeration value=\"shdw10\"/>\n      <xsd:enumeration value=\"shdw11\"/>\n      <xsd:enumeration value=\"shdw12\"/>\n      <xsd:enumeration value=\"shdw13\"/>\n      <xsd:enumeration value=\"shdw14\"/>\n      <xsd:enumeration value=\"shdw15\"/>\n      <xsd:enumeration value=\"shdw16\"/>\n      <xsd:enumeration value=\"shdw17\"/>\n      <xsd:enumeration value=\"shdw18\"/>\n      <xsd:enumeration value=\"shdw19\"/>\n      <xsd:enumeration value=\"shdw20\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetShadowEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetShadowVal\" use=\"required\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReflectionEffect\">\n    <xsd:attribute name=\"blurRad\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"stA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"stPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endA\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"endPos\" type=\"ST_PositiveFixedPercentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"dist\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fadeDir\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"5400000\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\" default=\"b\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RelativeOffsetEffect\">\n    <xsd:attribute name=\"tx\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Percentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SoftEdgesEffect\">\n    <xsd:attribute name=\"rad\" type=\"ST_PositiveCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TintEffect\">\n    <xsd:attribute name=\"hue\" type=\"ST_PositiveFixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"amt\" type=\"ST_FixedPercentage\" use=\"optional\" default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransformEffect\">\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"kx\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ky\" type=\"ST_FixedAngle\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NoFillProperties\"/>\n  <xsd:complexType name=\"CT_SolidColorFillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinearShadeProperties\">\n    <xsd:attribute name=\"ang\" type=\"ST_PositiveFixedAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"scaled\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PathShadeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"shape\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PathShadeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShadeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"path\" type=\"CT_PathShadeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TileFlipMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"x\"/>\n      <xsd:enumeration value=\"y\"/>\n      <xsd:enumeration value=\"xy\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pos\" type=\"ST_PositiveFixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tileRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TileInfoProperties\">\n    <xsd:attribute name=\"tx\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"ty\" type=\"ST_Coordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"sx\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"sy\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"flip\" type=\"ST_TileFlipMode\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_RectAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StretchInfoProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fillRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FillModeProperties\">\n    <xsd:choice>\n      <xsd:element name=\"tile\" type=\"CT_TileInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stretch\" type=\"CT_StretchInfoProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_BlipCompression\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"hqprint\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Blip\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Blob\"/>\n    <xsd:attribute name=\"cstate\" type=\"ST_BlipCompression\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlipFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"srcRect\" type=\"CT_RelativeRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillModeProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rotWithShape\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PresetPatternVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"ltHorz\"/>\n      <xsd:enumeration value=\"ltVert\"/>\n      <xsd:enumeration value=\"dkHorz\"/>\n      <xsd:enumeration value=\"dkVert\"/>\n      <xsd:enumeration value=\"narHorz\"/>\n      <xsd:enumeration value=\"narVert\"/>\n      <xsd:enumeration value=\"dashHorz\"/>\n      <xsd:enumeration value=\"dashVert\"/>\n      <xsd:enumeration value=\"cross\"/>\n      <xsd:enumeration value=\"dnDiag\"/>\n      <xsd:enumeration value=\"upDiag\"/>\n      <xsd:enumeration value=\"ltDnDiag\"/>\n      <xsd:enumeration value=\"ltUpDiag\"/>\n      <xsd:enumeration value=\"dkDnDiag\"/>\n      <xsd:enumeration value=\"dkUpDiag\"/>\n      <xsd:enumeration value=\"wdDnDiag\"/>\n      <xsd:enumeration value=\"wdUpDiag\"/>\n      <xsd:enumeration value=\"dashDnDiag\"/>\n      <xsd:enumeration value=\"dashUpDiag\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"smCheck\"/>\n      <xsd:enumeration value=\"lgCheck\"/>\n      <xsd:enumeration value=\"smGrid\"/>\n      <xsd:enumeration value=\"lgGrid\"/>\n      <xsd:enumeration value=\"dotGrid\"/>\n      <xsd:enumeration value=\"smConfetti\"/>\n      <xsd:enumeration value=\"lgConfetti\"/>\n      <xsd:enumeration value=\"horzBrick\"/>\n      <xsd:enumeration value=\"diagBrick\"/>\n      <xsd:enumeration value=\"solidDmnd\"/>\n      <xsd:enumeration value=\"openDmnd\"/>\n      <xsd:enumeration value=\"dotDmnd\"/>\n      <xsd:enumeration value=\"plaid\"/>\n      <xsd:enumeration value=\"sphere\"/>\n      <xsd:enumeration value=\"weave\"/>\n      <xsd:enumeration value=\"divot\"/>\n      <xsd:enumeration value=\"shingle\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"trellis\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PatternFillProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"fgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgClr\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_PresetPatternVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupFillProperties\"/>\n  <xsd:group name=\"EG_FillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpFill\" type=\"CT_GroupFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FillProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FillEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BlendMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"over\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"screen\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"lighten\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FillOverlayEffect\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectReference\">\n    <xsd:attribute name=\"ref\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Effect\">\n    <xsd:choice>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effect\" type=\"CT_EffectReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaBiLevel\" type=\"CT_AlphaBiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaCeiling\" type=\"CT_AlphaCeilingEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaFloor\" type=\"CT_AlphaFloorEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaInv\" type=\"CT_AlphaInverseEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaMod\" type=\"CT_AlphaModulateEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaModFix\" type=\"CT_AlphaModulateFixedEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaOutset\" type=\"CT_AlphaOutsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alphaRepl\" type=\"CT_AlphaReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"biLevel\" type=\"CT_BiLevelEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blend\" type=\"CT_BlendEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrChange\" type=\"CT_ColorChangeEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrRepl\" type=\"CT_ColorReplaceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"duotone\" type=\"CT_DuotoneEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_FillEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grayscl\" type=\"CT_GrayscaleEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hsl\" type=\"CT_HSLEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lum\" type=\"CT_LuminanceEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"relOff\" type=\"CT_RelativeOffsetEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tint\" type=\"CT_TintEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"CT_TransformEffect\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_EffectContainerType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sib\"/>\n      <xsd:enumeration value=\"tree\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EffectContainer\">\n    <xsd:group ref=\"EG_Effect\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"type\" type=\"ST_EffectContainerType\" use=\"optional\" default=\"sib\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AlphaModulateEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BlendEffect\">\n    <xsd:sequence>\n      <xsd:element name=\"cont\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"blend\" type=\"ST_BlendMode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EffectList\">\n    <xsd:sequence>\n      <xsd:element name=\"blur\" type=\"CT_BlurEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillOverlay\" type=\"CT_FillOverlayEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"glow\" type=\"CT_GlowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"innerShdw\" type=\"CT_InnerShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outerShdw\" type=\"CT_OuterShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstShdw\" type=\"CT_PresetShadowEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"reflection\" type=\"CT_ReflectionEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"softEdge\" type=\"CT_SoftEdgesEffect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_EffectProperties\">\n    <xsd:choice>\n      <xsd:element name=\"effectLst\" type=\"CT_EffectList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectDag\" type=\"CT_EffectContainer\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_EffectProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"blip\" type=\"CT_Blip\"/>\n  <xsd:simpleType name=\"ST_ShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"lineInv\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"rtTriangle\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"parallelogram\"/>\n      <xsd:enumeration value=\"trapezoid\"/>\n      <xsd:enumeration value=\"nonIsoscelesTrapezoid\"/>\n      <xsd:enumeration value=\"pentagon\"/>\n      <xsd:enumeration value=\"hexagon\"/>\n      <xsd:enumeration value=\"heptagon\"/>\n      <xsd:enumeration value=\"octagon\"/>\n      <xsd:enumeration value=\"decagon\"/>\n      <xsd:enumeration value=\"dodecagon\"/>\n      <xsd:enumeration value=\"star4\"/>\n      <xsd:enumeration value=\"star5\"/>\n      <xsd:enumeration value=\"star6\"/>\n      <xsd:enumeration value=\"star7\"/>\n      <xsd:enumeration value=\"star8\"/>\n      <xsd:enumeration value=\"star10\"/>\n      <xsd:enumeration value=\"star12\"/>\n      <xsd:enumeration value=\"star16\"/>\n      <xsd:enumeration value=\"star24\"/>\n      <xsd:enumeration value=\"star32\"/>\n      <xsd:enumeration value=\"roundRect\"/>\n      <xsd:enumeration value=\"round1Rect\"/>\n      <xsd:enumeration value=\"round2SameRect\"/>\n      <xsd:enumeration value=\"round2DiagRect\"/>\n      <xsd:enumeration value=\"snipRoundRect\"/>\n      <xsd:enumeration value=\"snip1Rect\"/>\n      <xsd:enumeration value=\"snip2SameRect\"/>\n      <xsd:enumeration value=\"snip2DiagRect\"/>\n      <xsd:enumeration value=\"plaque\"/>\n      <xsd:enumeration value=\"ellipse\"/>\n      <xsd:enumeration value=\"teardrop\"/>\n      <xsd:enumeration value=\"homePlate\"/>\n      <xsd:enumeration value=\"chevron\"/>\n      <xsd:enumeration value=\"pieWedge\"/>\n      <xsd:enumeration value=\"pie\"/>\n      <xsd:enumeration value=\"blockArc\"/>\n      <xsd:enumeration value=\"donut\"/>\n      <xsd:enumeration value=\"noSmoking\"/>\n      <xsd:enumeration value=\"rightArrow\"/>\n      <xsd:enumeration value=\"leftArrow\"/>\n      <xsd:enumeration value=\"upArrow\"/>\n      <xsd:enumeration value=\"downArrow\"/>\n      <xsd:enumeration value=\"stripedRightArrow\"/>\n      <xsd:enumeration value=\"notchedRightArrow\"/>\n      <xsd:enumeration value=\"bentUpArrow\"/>\n      <xsd:enumeration value=\"leftRightArrow\"/>\n      <xsd:enumeration value=\"upDownArrow\"/>\n      <xsd:enumeration value=\"leftUpArrow\"/>\n      <xsd:enumeration value=\"leftRightUpArrow\"/>\n      <xsd:enumeration value=\"quadArrow\"/>\n      <xsd:enumeration value=\"leftArrowCallout\"/>\n      <xsd:enumeration value=\"rightArrowCallout\"/>\n      <xsd:enumeration value=\"upArrowCallout\"/>\n      <xsd:enumeration value=\"downArrowCallout\"/>\n      <xsd:enumeration value=\"leftRightArrowCallout\"/>\n      <xsd:enumeration value=\"upDownArrowCallout\"/>\n      <xsd:enumeration value=\"quadArrowCallout\"/>\n      <xsd:enumeration value=\"bentArrow\"/>\n      <xsd:enumeration value=\"uturnArrow\"/>\n      <xsd:enumeration value=\"circularArrow\"/>\n      <xsd:enumeration value=\"leftCircularArrow\"/>\n      <xsd:enumeration value=\"leftRightCircularArrow\"/>\n      <xsd:enumeration value=\"curvedRightArrow\"/>\n      <xsd:enumeration value=\"curvedLeftArrow\"/>\n      <xsd:enumeration value=\"curvedUpArrow\"/>\n      <xsd:enumeration value=\"curvedDownArrow\"/>\n      <xsd:enumeration value=\"swooshArrow\"/>\n      <xsd:enumeration value=\"cube\"/>\n      <xsd:enumeration value=\"can\"/>\n      <xsd:enumeration value=\"lightningBolt\"/>\n      <xsd:enumeration value=\"heart\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"moon\"/>\n      <xsd:enumeration value=\"smileyFace\"/>\n      <xsd:enumeration value=\"irregularSeal1\"/>\n      <xsd:enumeration value=\"irregularSeal2\"/>\n      <xsd:enumeration value=\"foldedCorner\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"halfFrame\"/>\n      <xsd:enumeration value=\"corner\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"chord\"/>\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"leftBracket\"/>\n      <xsd:enumeration value=\"rightBracket\"/>\n      <xsd:enumeration value=\"leftBrace\"/>\n      <xsd:enumeration value=\"rightBrace\"/>\n      <xsd:enumeration value=\"bracketPair\"/>\n      <xsd:enumeration value=\"bracePair\"/>\n      <xsd:enumeration value=\"straightConnector1\"/>\n      <xsd:enumeration value=\"bentConnector2\"/>\n      <xsd:enumeration value=\"bentConnector3\"/>\n      <xsd:enumeration value=\"bentConnector4\"/>\n      <xsd:enumeration value=\"bentConnector5\"/>\n      <xsd:enumeration value=\"curvedConnector2\"/>\n      <xsd:enumeration value=\"curvedConnector3\"/>\n      <xsd:enumeration value=\"curvedConnector4\"/>\n      <xsd:enumeration value=\"curvedConnector5\"/>\n      <xsd:enumeration value=\"callout1\"/>\n      <xsd:enumeration value=\"callout2\"/>\n      <xsd:enumeration value=\"callout3\"/>\n      <xsd:enumeration value=\"accentCallout1\"/>\n      <xsd:enumeration value=\"accentCallout2\"/>\n      <xsd:enumeration value=\"accentCallout3\"/>\n      <xsd:enumeration value=\"borderCallout1\"/>\n      <xsd:enumeration value=\"borderCallout2\"/>\n      <xsd:enumeration value=\"borderCallout3\"/>\n      <xsd:enumeration value=\"accentBorderCallout1\"/>\n      <xsd:enumeration value=\"accentBorderCallout2\"/>\n      <xsd:enumeration value=\"accentBorderCallout3\"/>\n      <xsd:enumeration value=\"wedgeRectCallout\"/>\n      <xsd:enumeration value=\"wedgeRoundRectCallout\"/>\n      <xsd:enumeration value=\"wedgeEllipseCallout\"/>\n      <xsd:enumeration value=\"cloudCallout\"/>\n      <xsd:enumeration value=\"cloud\"/>\n      <xsd:enumeration value=\"ribbon\"/>\n      <xsd:enumeration value=\"ribbon2\"/>\n      <xsd:enumeration value=\"ellipseRibbon\"/>\n      <xsd:enumeration value=\"ellipseRibbon2\"/>\n      <xsd:enumeration value=\"leftRightRibbon\"/>\n      <xsd:enumeration value=\"verticalScroll\"/>\n      <xsd:enumeration value=\"horizontalScroll\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"plus\"/>\n      <xsd:enumeration value=\"flowChartProcess\"/>\n      <xsd:enumeration value=\"flowChartDecision\"/>\n      <xsd:enumeration value=\"flowChartInputOutput\"/>\n      <xsd:enumeration value=\"flowChartPredefinedProcess\"/>\n      <xsd:enumeration value=\"flowChartInternalStorage\"/>\n      <xsd:enumeration value=\"flowChartDocument\"/>\n      <xsd:enumeration value=\"flowChartMultidocument\"/>\n      <xsd:enumeration value=\"flowChartTerminator\"/>\n      <xsd:enumeration value=\"flowChartPreparation\"/>\n      <xsd:enumeration value=\"flowChartManualInput\"/>\n      <xsd:enumeration value=\"flowChartManualOperation\"/>\n      <xsd:enumeration value=\"flowChartConnector\"/>\n      <xsd:enumeration value=\"flowChartPunchedCard\"/>\n      <xsd:enumeration value=\"flowChartPunchedTape\"/>\n      <xsd:enumeration value=\"flowChartSummingJunction\"/>\n      <xsd:enumeration value=\"flowChartOr\"/>\n      <xsd:enumeration value=\"flowChartCollate\"/>\n      <xsd:enumeration value=\"flowChartSort\"/>\n      <xsd:enumeration value=\"flowChartExtract\"/>\n      <xsd:enumeration value=\"flowChartMerge\"/>\n      <xsd:enumeration value=\"flowChartOfflineStorage\"/>\n      <xsd:enumeration value=\"flowChartOnlineStorage\"/>\n      <xsd:enumeration value=\"flowChartMagneticTape\"/>\n      <xsd:enumeration value=\"flowChartMagneticDisk\"/>\n      <xsd:enumeration value=\"flowChartMagneticDrum\"/>\n      <xsd:enumeration value=\"flowChartDisplay\"/>\n      <xsd:enumeration value=\"flowChartDelay\"/>\n      <xsd:enumeration value=\"flowChartAlternateProcess\"/>\n      <xsd:enumeration value=\"flowChartOffpageConnector\"/>\n      <xsd:enumeration value=\"actionButtonBlank\"/>\n      <xsd:enumeration value=\"actionButtonHome\"/>\n      <xsd:enumeration value=\"actionButtonHelp\"/>\n      <xsd:enumeration value=\"actionButtonInformation\"/>\n      <xsd:enumeration value=\"actionButtonForwardNext\"/>\n      <xsd:enumeration value=\"actionButtonBackPrevious\"/>\n      <xsd:enumeration value=\"actionButtonEnd\"/>\n      <xsd:enumeration value=\"actionButtonBeginning\"/>\n      <xsd:enumeration value=\"actionButtonReturn\"/>\n      <xsd:enumeration value=\"actionButtonDocument\"/>\n      <xsd:enumeration value=\"actionButtonSound\"/>\n      <xsd:enumeration value=\"actionButtonMovie\"/>\n      <xsd:enumeration value=\"gear6\"/>\n      <xsd:enumeration value=\"gear9\"/>\n      <xsd:enumeration value=\"funnel\"/>\n      <xsd:enumeration value=\"mathPlus\"/>\n      <xsd:enumeration value=\"mathMinus\"/>\n      <xsd:enumeration value=\"mathMultiply\"/>\n      <xsd:enumeration value=\"mathDivide\"/>\n      <xsd:enumeration value=\"mathEqual\"/>\n      <xsd:enumeration value=\"mathNotEqual\"/>\n      <xsd:enumeration value=\"cornerTabs\"/>\n      <xsd:enumeration value=\"squareTabs\"/>\n      <xsd:enumeration value=\"plaqueTabs\"/>\n      <xsd:enumeration value=\"chartX\"/>\n      <xsd:enumeration value=\"chartStar\"/>\n      <xsd:enumeration value=\"chartPlus\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextShapeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"textNoShape\"/>\n      <xsd:enumeration value=\"textPlain\"/>\n      <xsd:enumeration value=\"textStop\"/>\n      <xsd:enumeration value=\"textTriangle\"/>\n      <xsd:enumeration value=\"textTriangleInverted\"/>\n      <xsd:enumeration value=\"textChevron\"/>\n      <xsd:enumeration value=\"textChevronInverted\"/>\n      <xsd:enumeration value=\"textRingInside\"/>\n      <xsd:enumeration value=\"textRingOutside\"/>\n      <xsd:enumeration value=\"textArchUp\"/>\n      <xsd:enumeration value=\"textArchDown\"/>\n      <xsd:enumeration value=\"textCircle\"/>\n      <xsd:enumeration value=\"textButton\"/>\n      <xsd:enumeration value=\"textArchUpPour\"/>\n      <xsd:enumeration value=\"textArchDownPour\"/>\n      <xsd:enumeration value=\"textCirclePour\"/>\n      <xsd:enumeration value=\"textButtonPour\"/>\n      <xsd:enumeration value=\"textCurveUp\"/>\n      <xsd:enumeration value=\"textCurveDown\"/>\n      <xsd:enumeration value=\"textCanUp\"/>\n      <xsd:enumeration value=\"textCanDown\"/>\n      <xsd:enumeration value=\"textWave1\"/>\n      <xsd:enumeration value=\"textWave2\"/>\n      <xsd:enumeration value=\"textDoubleWave1\"/>\n      <xsd:enumeration value=\"textWave4\"/>\n      <xsd:enumeration value=\"textInflate\"/>\n      <xsd:enumeration value=\"textDeflate\"/>\n      <xsd:enumeration value=\"textInflateBottom\"/>\n      <xsd:enumeration value=\"textDeflateBottom\"/>\n      <xsd:enumeration value=\"textInflateTop\"/>\n      <xsd:enumeration value=\"textDeflateTop\"/>\n      <xsd:enumeration value=\"textDeflateInflate\"/>\n      <xsd:enumeration value=\"textDeflateInflateDeflate\"/>\n      <xsd:enumeration value=\"textFadeRight\"/>\n      <xsd:enumeration value=\"textFadeLeft\"/>\n      <xsd:enumeration value=\"textFadeUp\"/>\n      <xsd:enumeration value=\"textFadeDown\"/>\n      <xsd:enumeration value=\"textSlantUp\"/>\n      <xsd:enumeration value=\"textSlantDown\"/>\n      <xsd:enumeration value=\"textCascadeUp\"/>\n      <xsd:enumeration value=\"textCascadeDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideName\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_GeomGuideFormula\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GeomGuide\">\n    <xsd:attribute name=\"name\" type=\"ST_GeomGuideName\" use=\"required\"/>\n    <xsd:attribute name=\"fmla\" type=\"ST_GeomGuideFormula\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomGuideList\">\n    <xsd:sequence>\n      <xsd:element name=\"gd\" type=\"CT_GeomGuide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AdjCoordinate\">\n    <xsd:union memberTypes=\"ST_Coordinate ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AdjAngle\">\n    <xsd:union memberTypes=\"ST_Angle ST_GeomGuideName\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_AdjPoint2D\">\n    <xsd:attribute name=\"x\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GeomRect\">\n    <xsd:attribute name=\"l\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XYAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefX\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxX\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefY\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxY\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolarAdjustHandle\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"gdRefR\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"maxR\" type=\"ST_AdjCoordinate\" use=\"optional\"/>\n    <xsd:attribute name=\"gdRefAng\" type=\"ST_GeomGuideName\" use=\"optional\"/>\n    <xsd:attribute name=\"minAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n    <xsd:attribute name=\"maxAng\" type=\"ST_AdjAngle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSite\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ang\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AdjustHandleList\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"ahXY\" type=\"CT_XYAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahPolar\" type=\"CT_PolarAdjustHandle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectionSiteList\">\n    <xsd:sequence>\n      <xsd:element name=\"cxn\" type=\"CT_ConnectionSite\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:attribute name=\"id\" type=\"ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DMoveTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DLineTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DArcTo\">\n    <xsd:attribute name=\"wR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"hR\" type=\"ST_AdjCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"stAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n    <xsd:attribute name=\"swAng\" type=\"ST_AdjAngle\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DQuadBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"2\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DCubicBezierTo\">\n    <xsd:sequence>\n      <xsd:element name=\"pt\" type=\"CT_AdjPoint2D\" minOccurs=\"3\" maxOccurs=\"3\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DClose\"/>\n  <xsd:simpleType name=\"ST_PathFillMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"norm\"/>\n      <xsd:enumeration value=\"lighten\"/>\n      <xsd:enumeration value=\"lightenLess\"/>\n      <xsd:enumeration value=\"darken\"/>\n      <xsd:enumeration value=\"darkenLess\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Path2D\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"close\" type=\"CT_Path2DClose\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_Path2DMoveTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTo\" type=\"CT_Path2DLineTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"arcTo\" type=\"CT_Path2DArcTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"quadBezTo\" type=\"CT_Path2DQuadBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cubicBezTo\" type=\"CT_Path2DCubicBezierTo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"w\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PositiveCoordinate\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_PathFillMode\" use=\"optional\" default=\"norm\"/>\n    <xsd:attribute name=\"stroke\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"extrusionOk\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path2DList\">\n    <xsd:sequence>\n      <xsd:element name=\"path\" type=\"CT_Path2D\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_ShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresetTextShape\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prst\" type=\"ST_TextShapeType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomGeometry2D\">\n    <xsd:sequence>\n      <xsd:element name=\"avLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gdLst\" type=\"CT_GeomGuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ahLst\" type=\"CT_AdjustHandleList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cxnLst\" type=\"CT_ConnectionSiteList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rect\" type=\"CT_GeomRect\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pathLst\" type=\"CT_Path2DList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Geometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstGeom\" type=\"CT_PresetGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextGeometry\">\n    <xsd:choice>\n      <xsd:element name=\"custGeom\" type=\"CT_CustomGeometry2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineEndType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"triangle\"/>\n      <xsd:enumeration value=\"stealth\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"arrow\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndWidth\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineEndLength\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sm\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"lg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineEndProperties\">\n    <xsd:attribute name=\"type\" type=\"ST_LineEndType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"w\" type=\"ST_LineEndWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"len\" type=\"ST_LineEndLength\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineFillProperties\">\n    <xsd:choice>\n      <xsd:element name=\"noFill\" type=\"CT_NoFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pattFill\" type=\"CT_PatternFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_LineJoinBevel\"/>\n  <xsd:complexType name=\"CT_LineJoinRound\"/>\n  <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n    <xsd:attribute name=\"lim\" type=\"ST_PositivePercentage\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineJoinProperties\">\n    <xsd:choice>\n      <xsd:element name=\"round\" type=\"CT_LineJoinRound\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bevel\" type=\"CT_LineJoinBevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PresetLineDashVal\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"lgDash\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"lgDashDot\"/>\n      <xsd:enumeration value=\"lgDashDotDot\"/>\n      <xsd:enumeration value=\"sysDash\"/>\n      <xsd:enumeration value=\"sysDot\"/>\n      <xsd:enumeration value=\"sysDashDot\"/>\n      <xsd:enumeration value=\"sysDashDotDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PresetLineDashProperties\">\n    <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStop\">\n    <xsd:attribute name=\"d\" type=\"ST_PositivePercentage\" use=\"required\"/>\n    <xsd:attribute name=\"sp\" type=\"ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DashStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"ds\" type=\"CT_DashStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_LineDashProperties\">\n    <xsd:choice>\n      <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDash\" type=\"CT_DashStopList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_LineCap\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rnd\"/>\n      <xsd:enumeration value=\"sq\"/>\n      <xsd:enumeration value=\"flat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineWidth\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"20116800\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PenAlignment\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CompoundLine\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"tri\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_LineFillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tailEnd\" type=\"CT_LineEndProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_LineWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_LineCap\" use=\"optional\"/>\n    <xsd:attribute name=\"cmpd\" type=\"ST_CompoundLine\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_PenAlignment\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShapeID\">\n    <xsd:restriction base=\"xsd:token\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Geometry\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sp3d\" type=\"CT_Shape3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"xfrm\" type=\"CT_GroupTransform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleMatrixReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_StyleMatrixColumnIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontReference\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"idx\" type=\"ST_FontCollectionIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefaultShapeDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"spPr\" type=\"CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectStyleDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"spDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txDef\" type=\"CT_DefaultShapeDefinition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_ColorMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bg1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"tx2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"hlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n    <xsd:attribute name=\"folHlink\" type=\"ST_ColorSchemeIndex\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMappingOverride\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"masterClrMapping\" type=\"CT_EmptyElement\"/>\n        <xsd:element name=\"overrideClrMapping\" type=\"CT_ColorMapping\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeAndMapping\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorSchemeList\">\n    <xsd:sequence>\n      <xsd:element name=\"extraClrScheme\" type=\"CT_ColorSchemeAndMapping\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OfficeStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"objectDefaults\" type=\"CT_ObjectStyleDefaults\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extraClrSchemeLst\" type=\"CT_ColorSchemeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custClrLst\" type=\"CT_CustomColorList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BaseStylesOverride\">\n    <xsd:sequence>\n      <xsd:element name=\"clrScheme\" type=\"CT_ColorScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontScheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fmtScheme\" type=\"CT_StyleMatrix\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipboardStyleSheet\">\n    <xsd:sequence>\n      <xsd:element name=\"themeElements\" type=\"CT_BaseStyles\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMap\" type=\"CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"theme\" type=\"CT_OfficeStyleSheet\"/>\n  <xsd:element name=\"themeOverride\" type=\"CT_BaseStylesOverride\"/>\n  <xsd:element name=\"themeManager\" type=\"CT_EmptyElement\"/>\n  <xsd:complexType name=\"CT_TableCellProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnL\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnR\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnT\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnB\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnTlToBr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnBlToTr\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_Coordinate32\" use=\"optional\" default=\"91440\"/>\n    <xsd:attribute name=\"marT\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"marB\" type=\"ST_Coordinate32\" use=\"optional\" default=\"45720\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\" default=\"t\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\" default=\"clip\"\n    />\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"xsd:string\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCol\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"w\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableGrid\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TableCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCell\">\n    <xsd:sequence>\n      <xsd:element name=\"txBody\" type=\"CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TableCellProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rowSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"gridSpan\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"hMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vMerge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableRow\">\n    <xsd:sequence>\n      <xsd:element name=\"tc\" type=\"CT_TableCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"h\" type=\"ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\"/>\n        <xsd:element name=\"tableStyleId\" type=\"s:ST_Guid\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"firstCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lastCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bandCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPr\" type=\"CT_TableProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TableGrid\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr\" type=\"CT_TableRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tbl\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Cell3D\">\n    <xsd:sequence>\n      <xsd:element name=\"bevel\" type=\"CT_Bevel\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lightRig\" type=\"CT_LightRig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\" default=\"plastic\"\n    />\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableFillStyle\">\n    <xsd:choice>\n      <xsd:element name=\"fill\" type=\"CT_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fillRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ThemeableLineStyle\">\n    <xsd:choice>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lnRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ThemeableEffectStyle\">\n    <xsd:choice>\n      <xsd:element name=\"effect\" type=\"CT_EffectProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"effectRef\" type=\"CT_StyleMatrixReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ThemeableFontStyles\">\n    <xsd:choice>\n      <xsd:element name=\"font\" type=\"CT_FontCollection\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fontRef\" type=\"CT_FontReference\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_OnOffStyleType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"def\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleTextStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFontStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"b\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n    <xsd:attribute name=\"i\" type=\"ST_OnOffStyleType\" use=\"optional\" default=\"def\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableCellBorderStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"left\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideH\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"insideV\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_ThemeableLineStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableBackgroundStyle\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableEffectStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleCellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcBdr\" type=\"CT_TableCellBorderStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ThemeableFillStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cell3D\" type=\"CT_Cell3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePartStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tcTxStyle\" type=\"CT_TableStyleTextStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcStyle\" type=\"CT_TableStyleCellStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tblBg\" type=\"CT_TableBackgroundStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wholeTbl\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2H\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band1V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"band2V\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstCol\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lastRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"seCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"swCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstRow\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"neCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nwCell\" type=\"CT_TablePartStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"styleName\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleList\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"def\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"tblStyleLst\" type=\"CT_TableStyleList\"/>\n  <xsd:complexType name=\"CT_TextParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"endParaRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAnchoringType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"dist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVertOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"ellipsis\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextHorzOverflowType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"overflow\"/>\n      <xsd:enumeration value=\"clip\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVerticalType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n      <xsd:enumeration value=\"vert270\"/>\n      <xsd:enumeration value=\"wordArtVert\"/>\n      <xsd:enumeration value=\"eaVert\"/>\n      <xsd:enumeration value=\"mongolianVert\"/>\n      <xsd:enumeration value=\"wordArtVertRtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextWrappingType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"square\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextColumnCount\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"16\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextListStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"defPPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl1pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl2pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl3pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl4pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl5pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl6pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl7pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl8pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lvl9pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextFontScalePercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextFontScalePercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontScalePercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"1000\"/>\n      <xsd:maxInclusive value=\"100000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextNormalAutofit\">\n    <xsd:attribute name=\"fontScale\" type=\"ST_TextFontScalePercentOrPercentString\" use=\"optional\"\n      default=\"100%\"/>\n    <xsd:attribute name=\"lnSpcReduction\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"optional\"\n      default=\"0%\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextShapeAutofit\"/>\n  <xsd:complexType name=\"CT_TextNoAutofit\"/>\n  <xsd:group name=\"EG_TextAutofit\">\n    <xsd:choice>\n      <xsd:element name=\"noAutofit\" type=\"CT_TextNoAutofit\"/>\n      <xsd:element name=\"normAutofit\" type=\"CT_TextNormalAutofit\"/>\n      <xsd:element name=\"spAutoFit\" type=\"CT_TextShapeAutofit\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBodyProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"prstTxWarp\" type=\"CT_PresetTextShape\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextAutofit\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scene3d\" type=\"CT_Scene3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_Text3D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rot\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"spcFirstLastPara\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"vertOverflow\" type=\"ST_TextVertOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"horzOverflow\" type=\"ST_TextHorzOverflowType\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"ST_TextVerticalType\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_TextWrappingType\" use=\"optional\"/>\n    <xsd:attribute name=\"lIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"tIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"bIns\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"numCol\" type=\"ST_TextColumnCount\" use=\"optional\"/>\n    <xsd:attribute name=\"spcCol\" type=\"ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtlCol\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fromWordArt\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"ST_TextAnchoringType\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorCtr\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"forceAA\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"upright\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatLnSpc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBody\">\n    <xsd:sequence>\n      <xsd:element name=\"bodyPr\" type=\"CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lstStyle\" type=\"CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"p\" type=\"CT_TextParagraph\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextBulletStartAtNum\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"32767\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextAutonumberScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"alphaLcParenBoth\"/>\n      <xsd:enumeration value=\"alphaUcParenBoth\"/>\n      <xsd:enumeration value=\"alphaLcParenR\"/>\n      <xsd:enumeration value=\"alphaUcParenR\"/>\n      <xsd:enumeration value=\"alphaLcPeriod\"/>\n      <xsd:enumeration value=\"alphaUcPeriod\"/>\n      <xsd:enumeration value=\"arabicParenBoth\"/>\n      <xsd:enumeration value=\"arabicParenR\"/>\n      <xsd:enumeration value=\"arabicPeriod\"/>\n      <xsd:enumeration value=\"arabicPlain\"/>\n      <xsd:enumeration value=\"romanLcParenBoth\"/>\n      <xsd:enumeration value=\"romanUcParenBoth\"/>\n      <xsd:enumeration value=\"romanLcParenR\"/>\n      <xsd:enumeration value=\"romanUcParenR\"/>\n      <xsd:enumeration value=\"romanLcPeriod\"/>\n      <xsd:enumeration value=\"romanUcPeriod\"/>\n      <xsd:enumeration value=\"circleNumDbPlain\"/>\n      <xsd:enumeration value=\"circleNumWdBlackPlain\"/>\n      <xsd:enumeration value=\"circleNumWdWhitePlain\"/>\n      <xsd:enumeration value=\"arabicDbPeriod\"/>\n      <xsd:enumeration value=\"arabicDbPlain\"/>\n      <xsd:enumeration value=\"ea1ChsPeriod\"/>\n      <xsd:enumeration value=\"ea1ChsPlain\"/>\n      <xsd:enumeration value=\"ea1ChtPeriod\"/>\n      <xsd:enumeration value=\"ea1ChtPlain\"/>\n      <xsd:enumeration value=\"ea1JpnChsDbPeriod\"/>\n      <xsd:enumeration value=\"ea1JpnKorPlain\"/>\n      <xsd:enumeration value=\"ea1JpnKorPeriod\"/>\n      <xsd:enumeration value=\"arabic1Minus\"/>\n      <xsd:enumeration value=\"arabic2Minus\"/>\n      <xsd:enumeration value=\"hebrew2Minus\"/>\n      <xsd:enumeration value=\"thaiAlphaPeriod\"/>\n      <xsd:enumeration value=\"thaiAlphaParenR\"/>\n      <xsd:enumeration value=\"thaiAlphaParenBoth\"/>\n      <xsd:enumeration value=\"thaiNumPeriod\"/>\n      <xsd:enumeration value=\"thaiNumParenR\"/>\n      <xsd:enumeration value=\"thaiNumParenBoth\"/>\n      <xsd:enumeration value=\"hindiAlphaPeriod\"/>\n      <xsd:enumeration value=\"hindiNumPeriod\"/>\n      <xsd:enumeration value=\"hindiNumParenR\"/>\n      <xsd:enumeration value=\"hindiAlpha1Period\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletColorFollowText\"/>\n  <xsd:group name=\"EG_TextBulletColor\">\n    <xsd:choice>\n      <xsd:element name=\"buClrTx\" type=\"CT_TextBulletColorFollowText\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"buClr\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextBulletSize\">\n    <xsd:union memberTypes=\"ST_TextBulletSizePercent ST_TextBulletSizeDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*((2[5-9])|([3-9][0-9])|([1-3][0-9][0-9])|400)%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextBulletSizeDecimal\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"25000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextBulletSizeFollowText\"/>\n  <xsd:complexType name=\"CT_TextBulletSizePercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextBulletSizePercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBulletSizePoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextFontSize\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextBulletSize\">\n    <xsd:choice>\n      <xsd:element name=\"buSzTx\" type=\"CT_TextBulletSizeFollowText\"/>\n      <xsd:element name=\"buSzPct\" type=\"CT_TextBulletSizePercent\"/>\n      <xsd:element name=\"buSzPts\" type=\"CT_TextBulletSizePoint\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextBulletTypefaceFollowText\"/>\n  <xsd:group name=\"EG_TextBulletTypeface\">\n    <xsd:choice>\n      <xsd:element name=\"buFontTx\" type=\"CT_TextBulletTypefaceFollowText\"/>\n      <xsd:element name=\"buFont\" type=\"CT_TextFont\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_TextAutonumberBullet\">\n    <xsd:attribute name=\"type\" type=\"ST_TextAutonumberScheme\" use=\"required\"/>\n    <xsd:attribute name=\"startAt\" type=\"ST_TextBulletStartAtNum\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextCharBullet\">\n    <xsd:attribute name=\"char\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextBlipBullet\">\n    <xsd:sequence>\n      <xsd:element name=\"blip\" type=\"CT_Blip\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextNoBullet\"/>\n  <xsd:group name=\"EG_TextBullet\">\n    <xsd:choice>\n      <xsd:element name=\"buNone\" type=\"CT_TextNoBullet\"/>\n      <xsd:element name=\"buAutoNum\" type=\"CT_TextAutonumberBullet\"/>\n      <xsd:element name=\"buChar\" type=\"CT_TextCharBullet\"/>\n      <xsd:element name=\"buBlip\" type=\"CT_TextBlipBullet\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextPoint\">\n    <xsd:union memberTypes=\"ST_TextPointUnqualified s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextPointUnqualified\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"-400000\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextNonNegativePoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontSize\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"100\"/>\n      <xsd:maxInclusive value=\"400000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTypeface\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PitchFamily\">\n   <xsd:restriction base=\"xsd:byte\">\n     <xsd:enumeration value=\"00\"/>\n     <xsd:enumeration value=\"01\"/>\n     <xsd:enumeration value=\"02\"/>\n     <xsd:enumeration value=\"16\"/>\n     <xsd:enumeration value=\"17\"/>\n     <xsd:enumeration value=\"18\"/>\n     <xsd:enumeration value=\"32\"/>\n     <xsd:enumeration value=\"33\"/>\n     <xsd:enumeration value=\"34\"/>\n     <xsd:enumeration value=\"48\"/>\n     <xsd:enumeration value=\"49\"/>\n     <xsd:enumeration value=\"50\"/>\n     <xsd:enumeration value=\"64\"/>\n     <xsd:enumeration value=\"65\"/>\n     <xsd:enumeration value=\"66\"/>\n     <xsd:enumeration value=\"80\"/>\n     <xsd:enumeration value=\"81\"/>\n     <xsd:enumeration value=\"82\"/>\n   </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_TextFont\">\n    <xsd:attribute name=\"typeface\" type=\"ST_TextTypeface\" use=\"required\"/>\n    <xsd:attribute name=\"panose\" type=\"s:ST_Panose\" use=\"optional\"/>\n    <xsd:attribute name=\"pitchFamily\" type=\"ST_PitchFamily\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"charset\" type=\"xsd:byte\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextUnderlineType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"sng\"/>\n      <xsd:enumeration value=\"dbl\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDashHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dotDotDashHeavy\"/>\n      <xsd:enumeration value=\"wavy\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDbl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextUnderlineLineFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillFollowText\"/>\n  <xsd:complexType name=\"CT_TextUnderlineFillGroupWrapper\">\n    <xsd:group ref=\"EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextUnderlineLine\">\n    <xsd:choice>\n      <xsd:element name=\"uLnTx\" type=\"CT_TextUnderlineLineFollowText\"/>\n      <xsd:element name=\"uLn\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_TextUnderlineFill\">\n    <xsd:choice>\n      <xsd:element name=\"uFillTx\" type=\"CT_TextUnderlineFillFollowText\"/>\n      <xsd:element name=\"uFill\" type=\"CT_TextUnderlineFillGroupWrapper\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_TextStrikeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"noStrike\"/>\n      <xsd:enumeration value=\"sngStrike\"/>\n      <xsd:enumeration value=\"dblStrike\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextCapsType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"small\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextCharacterProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"ln\" type=\"CT_LineProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineLine\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextUnderlineFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"latin\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ea\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cs\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sym\" type=\"CT_TextFont\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkClick\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hlinkMouseOver\" type=\"CT_Hyperlink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rtl\" type=\"CT_Boolean\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"kumimoji\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"altLang\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_TextFontSize\" use=\"optional\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"u\" type=\"ST_TextUnderlineType\" use=\"optional\"/>\n    <xsd:attribute name=\"strike\" type=\"ST_TextStrikeType\" use=\"optional\"/>\n    <xsd:attribute name=\"kern\" type=\"ST_TextNonNegativePoint\" use=\"optional\"/>\n    <xsd:attribute name=\"cap\" type=\"ST_TextCapsType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"spc\" type=\"ST_TextPoint\" use=\"optional\"/>\n    <xsd:attribute name=\"normalizeH\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"baseline\" type=\"ST_Percentage\" use=\"optional\"/>\n    <xsd:attribute name=\"noProof\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"dirty\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"err\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"smtClean\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"smtId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bmk\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextSpacingPoint\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"158400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercentOrPercentString\">\n    <xsd:union memberTypes=\"ST_TextSpacingPercent s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextSpacingPercent\">\n    <xsd:restriction base=\"ST_PercentageDecimal\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"13200000\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextSpacingPercent\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPercentOrPercentString\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacingPoint\">\n    <xsd:attribute name=\"val\" type=\"ST_TextSpacingPoint\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextMargin\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndent\">\n    <xsd:restriction base=\"ST_Coordinate32Unqualified\">\n      <xsd:minInclusive value=\"-51206400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextTabAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"dec\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextTabStop\">\n    <xsd:attribute name=\"pos\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextTabAlignType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextTabStopList\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TextTabStop\" minOccurs=\"0\" maxOccurs=\"32\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextLineBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextSpacing\">\n    <xsd:choice>\n      <xsd:element name=\"spcPct\" type=\"CT_TextSpacingPercent\"/>\n      <xsd:element name=\"spcPts\" type=\"CT_TextSpacingPoint\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"just\"/>\n      <xsd:enumeration value=\"justLow\"/>\n      <xsd:enumeration value=\"dist\"/>\n      <xsd:enumeration value=\"thaiDist\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextFontAlignType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"ctr\"/>\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"b\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextIndentLevelType\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"8\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextParagraphProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"lnSpc\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcBef\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spcAft\" type=\"CT_TextSpacing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletColor\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBulletTypeface\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TextBullet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tabLst\" type=\"CT_TextTabStopList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"defRPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"marL\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"marR\" type=\"ST_TextMargin\" use=\"optional\"/>\n    <xsd:attribute name=\"lvl\" type=\"ST_TextIndentLevelType\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"ST_TextIndent\" use=\"optional\"/>\n    <xsd:attribute name=\"algn\" type=\"ST_TextAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"defTabSz\" type=\"ST_Coordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"eaLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"fontAlgn\" type=\"ST_TextFontAlignType\" use=\"optional\"/>\n    <xsd:attribute name=\"latinLnBrk\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingPunct\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pPr\" type=\"CT_TextParagraphProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TextRun\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_RegularTextRun\"/>\n      <xsd:element name=\"br\" type=\"CT_TextLineBreak\"/>\n      <xsd:element name=\"fld\" type=\"CT_TextField\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RegularTextRun\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_TextCharacterProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"shared-relationshipReference.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>\n  <xsd:element name=\"from\" type=\"CT_Marker\"/>\n  <xsd:element name=\"to\" type=\"CT_Marker\"/>\n  <xsd:complexType name=\"CT_AnchorClientData\">\n    <xsd:attribute name=\"fLocksWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPrintsWithSheet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textlink\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fLocksText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"macro\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fPublished\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ObjectChoices\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ColID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RowID\">\n    <xsd:restriction base=\"xsd:int\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Marker\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"ST_ColID\"/>\n      <xsd:element name=\"colOff\" type=\"a:ST_Coordinate\"/>\n      <xsd:element name=\"row\" type=\"ST_RowID\"/>\n      <xsd:element name=\"rowOff\" type=\"a:ST_Coordinate\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"twoCell\"/>\n      <xsd:enumeration value=\"oneCell\"/>\n      <xsd:enumeration value=\"absolute\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TwoCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"to\" type=\"CT_Marker\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"editAs\" type=\"ST_EditAs\" use=\"optional\" default=\"twoCell\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OneCellAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"from\" type=\"CT_Marker\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbsoluteAnchor\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"ext\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:group ref=\"EG_ObjectChoices\"/>\n      <xsd:element name=\"clientData\" type=\"CT_AnchorClientData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Anchor\">\n    <xsd:choice>\n      <xsd:element name=\"twoCellAnchor\" type=\"CT_TwoCellAnchor\"/>\n      <xsd:element name=\"oneCellAnchor\" type=\"CT_OneCellAnchor\"/>\n      <xsd:element name=\"absoluteAnchor\" type=\"CT_AbsoluteAnchor\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Anchor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wsDr\" type=\"CT_Drawing\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:dpct=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  targetNamespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import schemaLocation=\"wml.xsd\"\n    namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"\n    schemaLocation=\"dml-picture.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:complexType name=\"CT_EffectExtent\">\n    <xsd:attribute name=\"l\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"t\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"a:ST_Coordinate\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_Coordinate\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapDistance\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Inline\">\n    <xsd:sequence>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WrapText\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bothSides\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WrapPath\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"lineTo\" type=\"a:CT_Point2D\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"edited\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapNone\"/>\n  <xsd:complexType name=\"CT_WrapSquare\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTight\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapThrough\">\n    <xsd:sequence>\n      <xsd:element name=\"wrapPolygon\" type=\"CT_WrapPath\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"wrapText\" type=\"ST_WrapText\" use=\"required\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WrapTopBottom\">\n    <xsd:sequence>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_WrapType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"wrapNone\" type=\"CT_WrapNone\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapSquare\" type=\"CT_WrapSquare\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTight\" type=\"CT_WrapTight\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapThrough\" type=\"CT_WrapThrough\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"wrapTopAndBottom\" type=\"CT_WrapTopBottom\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:simpleType name=\"ST_PositionOffset\">\n    <xsd:restriction base=\"xsd:int\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlignH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromH\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"leftMargin\"/>\n      <xsd:enumeration value=\"rightMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosH\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignH\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromH\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlignV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RelFromV\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"line\"/>\n      <xsd:enumeration value=\"topMargin\"/>\n      <xsd:enumeration value=\"bottomMargin\"/>\n      <xsd:enumeration value=\"insideMargin\"/>\n      <xsd:enumeration value=\"outsideMargin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PosV\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"align\" type=\"ST_AlignV\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"posOffset\" type=\"ST_PositionOffset\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"relativeFrom\" type=\"ST_RelFromV\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Anchor\">\n    <xsd:sequence>\n      <xsd:element name=\"simplePos\" type=\"a:CT_Point2D\"/>\n      <xsd:element name=\"positionH\" type=\"CT_PosH\"/>\n      <xsd:element name=\"positionV\" type=\"CT_PosV\"/>\n      <xsd:element name=\"extent\" type=\"a:CT_PositiveSize2D\"/>\n      <xsd:element name=\"effectExtent\" type=\"CT_EffectExtent\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_WrapType\"/>\n      <xsd:element name=\"docPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"distT\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distB\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distL\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"distR\" type=\"ST_WrapDistance\" use=\"optional\"/>\n    <xsd:attribute name=\"simplePos\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"relativeHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"behindDoc\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"layoutInCell\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"allowOverlap\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"w:EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextboxInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LinkedTextboxInformation\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"seq\" type=\"xsd:unsignedShort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingShape\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n        <xsd:element name=\"cNvCnPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"txbx\" type=\"CT_TextboxInfo\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"linkedTxbx\" type=\"CT_LinkedTextboxInformation\" minOccurs=\"1\"\n          maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"bodyPr\" type=\"a:CT_TextBodyProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"normalEastAsianFlow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvFrPr\" type=\"a:CT_NonVisualGraphicFrameProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPartNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvContentPartPr\" type=\"a:CT_NonVisualContentPartProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingContentPart\">\n    <xsd:sequence>\n      <xsd:element name=\"nvContentPartPr\" type=\"CT_WordprocessingContentPartNonVisual\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingGroup\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_WordprocessingGroup\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WordprocessingCanvas\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"a:CT_BackgroundFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"whole\" type=\"a:CT_WholeE2oFormatting\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element ref=\"wsp\"/>\n        <xsd:element ref=\"dpct:pic\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_WordprocessingContentPart\"/>\n        <xsd:element ref=\"wgp\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicFrame\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"a:CT_OfficeArtExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"wpc\" type=\"CT_WordprocessingCanvas\"/>\n  <xsd:element name=\"wgp\" type=\"CT_WordprocessingGroup\"/>\n  <xsd:element name=\"wsp\" type=\"CT_WordprocessingShape\"/>\n  <xsd:element name=\"inline\" type=\"CT_Inline\"/>\n  <xsd:element name=\"anchor\" type=\"CT_Anchor\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"\n  xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\"\n    schemaLocation=\"dml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_TransitionSideDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"l\"/>\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"d\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionCornerDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"lu\"/>\n      <xsd:enumeration value=\"ru\"/>\n      <xsd:enumeration value=\"ld\"/>\n      <xsd:enumeration value=\"rd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TransitionInOutDirectionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"in\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SideDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionSideDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CornerDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionCornerDirectionType\" use=\"optional\" default=\"lu\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionEightDirectionType\">\n    <xsd:union memberTypes=\"ST_TransitionSideDirectionType ST_TransitionCornerDirectionType\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EightDirectionTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionEightDirectionType\" use=\"optional\" default=\"l\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OrientationTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InOutTransition\">\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptionalBlackTransition\">\n    <xsd:attribute name=\"thruBlk\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SplitTransition\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TransitionInOutDirectionType\" use=\"optional\" default=\"out\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WheelTransition\">\n    <xsd:attribute name=\"spokes\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"4\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionStartSoundAction\">\n    <xsd:sequence>\n      <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"snd\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TransitionSoundAction\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"stSnd\" type=\"CT_TransitionStartSoundAction\"/>\n      <xsd:element name=\"endSnd\" type=\"CT_Empty\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TransitionSpeed\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slow\"/>\n      <xsd:enumeration value=\"med\"/>\n      <xsd:enumeration value=\"fast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideTransition\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"blinds\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"checker\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"circle\" type=\"CT_Empty\"/>\n        <xsd:element name=\"dissolve\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comb\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"cover\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"cut\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"diamond\" type=\"CT_Empty\"/>\n        <xsd:element name=\"fade\" type=\"CT_OptionalBlackTransition\"/>\n        <xsd:element name=\"newsflash\" type=\"CT_Empty\"/>\n        <xsd:element name=\"plus\" type=\"CT_Empty\"/>\n        <xsd:element name=\"pull\" type=\"CT_EightDirectionTransition\"/>\n        <xsd:element name=\"push\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"random\" type=\"CT_Empty\"/>\n        <xsd:element name=\"randomBar\" type=\"CT_OrientationTransition\"/>\n        <xsd:element name=\"split\" type=\"CT_SplitTransition\"/>\n        <xsd:element name=\"strips\" type=\"CT_CornerDirectionTransition\"/>\n        <xsd:element name=\"wedge\" type=\"CT_Empty\"/>\n        <xsd:element name=\"wheel\" type=\"CT_WheelTransition\"/>\n        <xsd:element name=\"wipe\" type=\"CT_SideDirectionTransition\"/>\n        <xsd:element name=\"zoom\" type=\"CT_InOutTransition\"/>\n      </xsd:choice>\n      <xsd:element name=\"sndAc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TransitionSoundAction\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"spd\" type=\"ST_TransitionSpeed\" use=\"optional\" default=\"fast\"/>\n    <xsd:attribute name=\"advClick\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"advTm\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeIndefinite\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"indefinite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTime\">\n    <xsd:union memberTypes=\"xsd:unsignedInt ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeID\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateIntervalTime\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLIterateIntervalPercentage\">\n    <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_IterateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"el\"/>\n      <xsd:enumeration value=\"wd\"/>\n      <xsd:enumeration value=\"lt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLIterateData\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"tmAbs\" type=\"CT_TLIterateIntervalTime\"/>\n      <xsd:element name=\"tmPct\" type=\"CT_TLIterateIntervalPercentage\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_IterateType\" use=\"optional\" default=\"el\"/>\n    <xsd:attribute name=\"backwards\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSubShapeId\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTextTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"charRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"pRg\" type=\"CT_IndexRange\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLChartSubelementType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"gridLegend\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"ptInSeries\"/>\n      <xsd:enumeration value=\"ptInCategory\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleChartTargetElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TLChartSubelementType\" use=\"required\"/>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLShapeTargetElement\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bg\" type=\"CT_Empty\"/>\n      <xsd:element name=\"subSp\" type=\"CT_TLSubShapeId\"/>\n      <xsd:element name=\"oleChartEl\" type=\"CT_TLOleChartTargetElement\"/>\n      <xsd:element name=\"txEl\" type=\"CT_TLTextTargetElement\"/>\n      <xsd:element name=\"graphicEl\" type=\"a:CT_AnimationElementChoice\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeTargetElement\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"sldTgt\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sndTgt\" type=\"a:CT_EmbeddedWAVAudioFile\"/>\n      <xsd:element name=\"spTgt\" type=\"CT_TLShapeTargetElement\"/>\n      <xsd:element name=\"inkTgt\" type=\"CT_TLSubShapeId\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTriggerTimeNodeID\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTimeNodeID\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerRuntimeNode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"first\"/>\n      <xsd:enumeration value=\"last\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTriggerRuntimeNode\">\n    <xsd:attribute name=\"val\" type=\"ST_TLTriggerRuntimeNode\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTriggerEvent\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"onBegin\"/>\n      <xsd:enumeration value=\"onEnd\"/>\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"onClick\"/>\n      <xsd:enumeration value=\"onDblClick\"/>\n      <xsd:enumeration value=\"onMouseOver\"/>\n      <xsd:enumeration value=\"onMouseOut\"/>\n      <xsd:enumeration value=\"onNext\"/>\n      <xsd:enumeration value=\"onPrev\"/>\n      <xsd:enumeration value=\"onStopAudio\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeCondition\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\"/>\n      <xsd:element name=\"tn\" type=\"CT_TLTriggerTimeNodeID\"/>\n      <xsd:element name=\"rtn\" type=\"CT_TLTriggerRuntimeNode\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"evt\" use=\"optional\" type=\"ST_TLTriggerEvent\"/>\n    <xsd:attribute name=\"delay\" type=\"ST_TLTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeConditionList\">\n    <xsd:sequence>\n      <xsd:element name=\"cond\" type=\"CT_TLTimeCondition\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TimeNodeList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"par\" type=\"CT_TLTimeNodeParallel\"/>\n      <xsd:element name=\"seq\" type=\"CT_TLTimeNodeSequence\"/>\n      <xsd:element name=\"excl\" type=\"CT_TLTimeNodeExclusive\"/>\n      <xsd:element name=\"anim\" type=\"CT_TLAnimateBehavior\"/>\n      <xsd:element name=\"animClr\" type=\"CT_TLAnimateColorBehavior\"/>\n      <xsd:element name=\"animEffect\" type=\"CT_TLAnimateEffectBehavior\"/>\n      <xsd:element name=\"animMotion\" type=\"CT_TLAnimateMotionBehavior\"/>\n      <xsd:element name=\"animRot\" type=\"CT_TLAnimateRotationBehavior\"/>\n      <xsd:element name=\"animScale\" type=\"CT_TLAnimateScaleBehavior\"/>\n      <xsd:element name=\"cmd\" type=\"CT_TLCommandBehavior\"/>\n      <xsd:element name=\"set\" type=\"CT_TLSetBehavior\"/>\n      <xsd:element name=\"audio\" type=\"CT_TLMediaNodeAudio\"/>\n      <xsd:element name=\"video\" type=\"CT_TLMediaNodeVideo\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeNodePresetClassType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"entr\"/>\n      <xsd:enumeration value=\"exit\"/>\n      <xsd:enumeration value=\"emph\"/>\n      <xsd:enumeration value=\"path\"/>\n      <xsd:enumeration value=\"verb\"/>\n      <xsd:enumeration value=\"mediacall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeRestartType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"whenNotActive\"/>\n      <xsd:enumeration value=\"never\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeFillType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"remove\"/>\n      <xsd:enumeration value=\"freeze\"/>\n      <xsd:enumeration value=\"hold\"/>\n      <xsd:enumeration value=\"transition\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeSyncType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"canSlip\"/>\n      <xsd:enumeration value=\"locked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeMasterRelation\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sameClick\"/>\n      <xsd:enumeration value=\"lastClick\"/>\n      <xsd:enumeration value=\"nextClick\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLTimeNodeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"clickEffect\"/>\n      <xsd:enumeration value=\"withEffect\"/>\n      <xsd:enumeration value=\"afterEffect\"/>\n      <xsd:enumeration value=\"mainSeq\"/>\n      <xsd:enumeration value=\"interactiveSeq\"/>\n      <xsd:enumeration value=\"clickPar\"/>\n      <xsd:enumeration value=\"withGroup\"/>\n      <xsd:enumeration value=\"afterGroup\"/>\n      <xsd:enumeration value=\"tmRoot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonTimeNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"stCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"endSync\" type=\"CT_TLTimeCondition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iterate\" type=\"CT_TLIterateData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"childTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"subTnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_TLTimeNodeID\" use=\"optional\"/>\n    <xsd:attribute name=\"presetID\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"presetClass\" type=\"ST_TLTimeNodePresetClassType\" use=\"optional\"/>\n    <xsd:attribute name=\"presetSubtype\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"dur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"repeatCount\" type=\"ST_TLTime\" use=\"optional\" default=\"1000\"/>\n    <xsd:attribute name=\"repeatDur\" type=\"ST_TLTime\" use=\"optional\"/>\n    <xsd:attribute name=\"spd\" type=\"a:ST_Percentage\" use=\"optional\" default=\"100%\"/>\n    <xsd:attribute name=\"accel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"decel\" type=\"a:ST_PositiveFixedPercentage\" use=\"optional\" default=\"0%\"/>\n    <xsd:attribute name=\"autoRev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_TLTimeNodeRestartType\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_TLTimeNodeFillType\" use=\"optional\"/>\n    <xsd:attribute name=\"syncBehavior\" type=\"ST_TLTimeNodeSyncType\" use=\"optional\"/>\n    <xsd:attribute name=\"tmFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"evtFilter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"masterRel\" type=\"ST_TLTimeNodeMasterRelation\" use=\"optional\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"afterEffect\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nodeType\" type=\"ST_TLTimeNodeType\" use=\"optional\"/>\n    <xsd:attribute name=\"nodePh\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeParallel\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLNextActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"seek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLPreviousActionType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"skipTimed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeNodeSequence\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prevCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nextCondLst\" type=\"CT_TLTimeConditionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"concurrent\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"prevAc\" type=\"ST_TLPreviousActionType\" use=\"optional\"/>\n    <xsd:attribute name=\"nextAc\" type=\"ST_TLNextActionType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeNodeExclusive\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLBehaviorAttributeNameList\">\n    <xsd:sequence>\n      <xsd:element name=\"attrName\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLBehaviorAdditiveType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"base\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"repl\"/>\n      <xsd:enumeration value=\"mult\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorAccumulateType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorTransformType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"pt\"/>\n      <xsd:enumeration value=\"img\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLBehaviorOverrideType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"childStyle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommonBehaviorData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attrNameLst\" type=\"CT_TLBehaviorAttributeNameList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"additive\" type=\"ST_TLBehaviorAdditiveType\" use=\"optional\"/>\n    <xsd:attribute name=\"accumulate\" type=\"ST_TLBehaviorAccumulateType\" use=\"optional\"/>\n    <xsd:attribute name=\"xfrmType\" type=\"ST_TLBehaviorTransformType\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rctx\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"override\" type=\"ST_TLBehaviorOverrideType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantBooleanVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantIntegerVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantFloatVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:float\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariantStringVal\">\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimVariant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"boolVal\" type=\"CT_TLAnimVariantBooleanVal\"/>\n      <xsd:element name=\"intVal\" type=\"CT_TLAnimVariantIntegerVal\"/>\n      <xsd:element name=\"fltVal\" type=\"CT_TLAnimVariantFloatVal\"/>\n      <xsd:element name=\"strVal\" type=\"CT_TLAnimVariantStringVal\"/>\n      <xsd:element name=\"clrVal\" type=\"a:CT_Color\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLTimeAnimateValueTime\">\n    <xsd:union memberTypes=\"a:ST_PositiveFixedPercentage ST_TLTimeIndefinite\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tm\" type=\"ST_TLTimeAnimateValueTime\" use=\"optional\" default=\"indefinite\"/>\n    <xsd:attribute name=\"fmla\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTimeAnimateValueList\">\n    <xsd:sequence>\n      <xsd:element name=\"tav\" type=\"CT_TLTimeAnimateValue\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorCalcMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"discrete\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"fmla\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateBehaviorValueType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tavLst\" type=\"CT_TLTimeAnimateValueList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"calcmode\" type=\"ST_TLAnimateBehaviorCalcMode\" use=\"optional\"/>\n    <xsd:attribute name=\"valueType\" type=\"ST_TLAnimateBehaviorValueType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByRgbColorTransform\">\n    <xsd:attribute name=\"r\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"g\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"b\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByHslColorTransform\">\n    <xsd:attribute name=\"h\" type=\"a:ST_Angle\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"l\" type=\"a:ST_FixedPercentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLByAnimateColorTransform\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"rgb\" type=\"CT_TLByRgbColorTransform\"/>\n      <xsd:element name=\"hsl\" type=\"CT_TLByHslColorTransform\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateColorSpace\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"rgb\"/>\n      <xsd:enumeration value=\"hsl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateColorDirection\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"ccw\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateColorBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLByAnimateColorTransform\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"clrSpc\" type=\"ST_TLAnimateColorSpace\" use=\"optional\"/>\n    <xsd:attribute name=\"dir\" type=\"ST_TLAnimateColorDirection\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateEffectTransition\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"in\"/>\n      <xsd:enumeration value=\"out\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLAnimateEffectBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"progress\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"transition\" type=\"ST_TLAnimateEffectTransition\" default=\"in\" use=\"optional\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"prLst\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionBehaviorOrigin\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"parent\"/>\n      <xsd:enumeration value=\"layout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TLAnimateMotionPathEditMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"relative\"/>\n      <xsd:enumeration value=\"fixed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLPoint\">\n    <xsd:attribute name=\"x\" type=\"a:ST_Percentage\" use=\"required\"/>\n    <xsd:attribute name=\"y\" type=\"a:ST_Percentage\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateMotionBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rCtr\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"origin\" type=\"ST_TLAnimateMotionBehaviorOrigin\" use=\"optional\"/>\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"pathEditMode\" type=\"ST_TLAnimateMotionPathEditMode\" use=\"optional\"/>\n    <xsd:attribute name=\"rAng\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"ptsTypes\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateRotationBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"by\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"from\" type=\"a:ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"a:ST_Angle\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLAnimateScaleBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"by\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"from\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLPoint\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zoomContents\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLCommandType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"evt\"/>\n      <xsd:enumeration value=\"call\"/>\n      <xsd:enumeration value=\"verb\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLCommandBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute type=\"ST_TLCommandType\" name=\"type\" use=\"optional\"/>\n    <xsd:attribute name=\"cmd\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLSetBehavior\">\n    <xsd:sequence>\n      <xsd:element name=\"cBhvr\" type=\"CT_TLCommonBehaviorData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"to\" type=\"CT_TLAnimVariant\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLCommonMediaNodeData\">\n    <xsd:sequence>\n      <xsd:element name=\"cTn\" type=\"CT_TLCommonTimeNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tgtEl\" type=\"CT_TLTimeTargetElement\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"vol\" type=\"a:ST_PositiveFixedPercentage\" default=\"50%\" use=\"optional\"/>\n    <xsd:attribute name=\"mute\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numSld\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showWhenStopped\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeAudio\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLMediaNodeVideo\">\n    <xsd:sequence>\n      <xsd:element name=\"cMediaNode\" type=\"CT_TLCommonMediaNodeData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullScrn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_TLBuild\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_DrawingElementId\" use=\"required\"/>\n    <xsd:attribute name=\"grpId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uiExpand\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_TLTemplate\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLTemplateList\">\n    <xsd:sequence>\n      <xsd:element name=\"tmpl\" type=\"CT_TLTemplate\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLParaBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"whole\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildParagraph\">\n    <xsd:sequence>\n      <xsd:element name=\"tmplLst\" type=\"CT_TLTemplateList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"build\" type=\"ST_TLParaBuildType\" use=\"optional\" default=\"whole\"/>\n    <xsd:attribute name=\"bldLvl\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoUpdateAnimBg\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n    <xsd:attribute name=\"rev\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advAuto\" type=\"ST_TLTime\" use=\"optional\" default=\"indefinite\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLDiagramBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"depthByNode\"/>\n      <xsd:enumeration value=\"depthByBranch\"/>\n      <xsd:enumeration value=\"breadthByNode\"/>\n      <xsd:enumeration value=\"breadthByLvl\"/>\n      <xsd:enumeration value=\"cw\"/>\n      <xsd:enumeration value=\"cwIn\"/>\n      <xsd:enumeration value=\"cwOut\"/>\n      <xsd:enumeration value=\"ccw\"/>\n      <xsd:enumeration value=\"ccwIn\"/>\n      <xsd:enumeration value=\"ccwOut\"/>\n      <xsd:enumeration value=\"inByRing\"/>\n      <xsd:enumeration value=\"outByRing\"/>\n      <xsd:enumeration value=\"up\"/>\n      <xsd:enumeration value=\"down\"/>\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"cust\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLBuildDiagram\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLDiagramBuildType\" use=\"optional\" default=\"whole\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TLOleChartBuildType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"allAtOnce\"/>\n      <xsd:enumeration value=\"series\"/>\n      <xsd:enumeration value=\"category\"/>\n      <xsd:enumeration value=\"seriesEl\"/>\n      <xsd:enumeration value=\"categoryEl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TLOleBuildChart\">\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n    <xsd:attribute name=\"bld\" type=\"ST_TLOleChartBuildType\" use=\"optional\" default=\"allAtOnce\"/>\n    <xsd:attribute name=\"animBg\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TLGraphicalObjectBuild\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"bldAsOne\" type=\"CT_Empty\"/>\n      <xsd:element name=\"bldSub\" type=\"a:CT_AnimationGraphicalObjectBuildProperties\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_TLBuild\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BuildList\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bldP\" type=\"CT_TLBuildParagraph\"/>\n      <xsd:element name=\"bldDgm\" type=\"CT_TLBuildDiagram\"/>\n      <xsd:element name=\"bldOleChart\" type=\"CT_TLOleBuildChart\"/>\n      <xsd:element name=\"bldGraphic\" type=\"CT_TLGraphicalObjectBuild\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideTiming\">\n    <xsd:sequence>\n      <xsd:element name=\"tnLst\" type=\"CT_TimeNodeList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bldLst\" type=\"CT_BuildList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:simpleType name=\"ST_Name\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"horz\"/>\n      <xsd:enumeration value=\"vert\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Index\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IndexRange\">\n    <xsd:attribute name=\"st\" type=\"ST_Index\" use=\"required\"/>\n    <xsd:attribute name=\"end\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipListEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideRelationshipList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_SlideRelationshipListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowId\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SlideListChoice\">\n    <xsd:choice>\n      <xsd:element name=\"sldAll\" type=\"CT_Empty\"/>\n      <xsd:element name=\"sldRg\" type=\"CT_IndexRange\"/>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShowId\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_CustomerData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagsData\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomerDataList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"custData\" type=\"CT_CustomerData\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tags\" type=\"CT_TagsData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExtensionListModify\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mod\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthor\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"initials\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"lastIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"clrIdx\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentAuthorList\">\n    <xsd:sequence>\n      <xsd:element name=\"cmAuthor\" type=\"CT_CommentAuthor\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmAuthorLst\" type=\"CT_CommentAuthorList\"/>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"text\" type=\"xsd:string\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"idx\" type=\"ST_Index\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"cm\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"cmLst\" type=\"CT_CommentList\"/>\n  <xsd:attributeGroup name=\"AG_Ole\">\n    <xsd:attribute name=\"spid\" type=\"a:ST_ShapeID\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"showAsIcon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"imgW\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n    <xsd:attribute name=\"imgH\" type=\"a:ST_PositiveCoordinate32\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:simpleType name=\"ST_OleObjectFollowColorScheme\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"textAndBackground\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleObjectEmbed\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"followColorScheme\" type=\"ST_OleObjectFollowColorScheme\" use=\"optional\"\n      default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjectLink\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"updateAutomatic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n        <xsd:element name=\"embed\" type=\"CT_OleObjectEmbed\"/>\n        <xsd:element name=\"link\" type=\"CT_OleObjectLink\"/>\n      </xsd:choice>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"oleObj\" type=\"CT_OleObject\"/>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pic\" type=\"CT_Picture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Ole\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlList\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"256\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideId\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldId\" type=\"CT_SlideIdListEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideMasterId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideMasterId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterId\" type=\"CT_SlideMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"notesMasterId\" type=\"CT_NotesMasterIdListEntry\" minOccurs=\"0\" maxOccurs=\"1\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HandoutMasterIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"handoutMasterId\" type=\"CT_HandoutMasterIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontDataId\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"a:CT_TextFont\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"regular\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bold\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"italic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"boldItalic\" type=\"CT_EmbeddedFontDataId\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EmbeddedFontList\">\n    <xsd:sequence>\n      <xsd:element name=\"embeddedFont\" type=\"CT_EmbeddedFontListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShow\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLst\" type=\"CT_SlideRelationshipList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"ST_Name\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomShowList\">\n    <xsd:sequence>\n      <xsd:element name=\"custShow\" type=\"CT_CustomShow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhotoAlbumLayout\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"fitToSlide\"/>\n      <xsd:enumeration value=\"1pic\"/>\n      <xsd:enumeration value=\"2pic\"/>\n      <xsd:enumeration value=\"4pic\"/>\n      <xsd:enumeration value=\"1picTitle\"/>\n      <xsd:enumeration value=\"2picTitle\"/>\n      <xsd:enumeration value=\"4picTitle\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhotoAlbumFrameShape\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"frameStyle1\"/>\n      <xsd:enumeration value=\"frameStyle2\"/>\n      <xsd:enumeration value=\"frameStyle3\"/>\n      <xsd:enumeration value=\"frameStyle4\"/>\n      <xsd:enumeration value=\"frameStyle5\"/>\n      <xsd:enumeration value=\"frameStyle6\"/>\n      <xsd:enumeration value=\"frameStyle7\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhotoAlbum\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bw\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showCaptions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"layout\" type=\"ST_PhotoAlbumLayout\" use=\"optional\" default=\"fitToSlide\"/>\n    <xsd:attribute name=\"frame\" type=\"ST_PhotoAlbumFrameShape\" use=\"optional\" default=\"frameStyle1\"\n    />\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideSizeCoordinate\">\n    <xsd:restriction base=\"a:ST_PositiveCoordinate32\">\n      <xsd:minInclusive value=\"914400\"/>\n      <xsd:maxInclusive value=\"51206400\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SlideSizeType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"screen4x3\"/>\n      <xsd:enumeration value=\"letter\"/>\n      <xsd:enumeration value=\"A4\"/>\n      <xsd:enumeration value=\"35mm\"/>\n      <xsd:enumeration value=\"overhead\"/>\n      <xsd:enumeration value=\"banner\"/>\n      <xsd:enumeration value=\"custom\"/>\n      <xsd:enumeration value=\"ledger\"/>\n      <xsd:enumeration value=\"A3\"/>\n      <xsd:enumeration value=\"B4ISO\"/>\n      <xsd:enumeration value=\"B5ISO\"/>\n      <xsd:enumeration value=\"B4JIS\"/>\n      <xsd:enumeration value=\"B5JIS\"/>\n      <xsd:enumeration value=\"hagakiCard\"/>\n      <xsd:enumeration value=\"screen16x9\"/>\n      <xsd:enumeration value=\"screen16x10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideSize\">\n    <xsd:attribute name=\"cx\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"cy\" type=\"ST_SlideSizeCoordinate\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideSizeType\" use=\"optional\" default=\"custom\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"invalStChars\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"invalEndChars\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BookmarkIdSeed\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxExclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ModifyVerifier\">\n    <xsd:attribute name=\"algorithmName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinValue\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"saltData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"hashData\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Presentation\">\n    <xsd:sequence>\n      <xsd:element name=\"sldMasterIdLst\" type=\"CT_SlideMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesMasterIdLst\" type=\"CT_NotesMasterIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"handoutMasterIdLst\" type=\"CT_HandoutMasterIdList\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sldIdLst\" type=\"CT_SlideIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldSz\" type=\"CT_SlideSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesSz\" type=\"a:CT_PositiveSize2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embeddedFontLst\" type=\"CT_EmbeddedFontList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custShowLst\" type=\"CT_CustomShowList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"photoAlbum\" type=\"CT_PhotoAlbum\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTextStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"modifyVerifier\" type=\"CT_ModifyVerifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverZoom\" type=\"a:ST_Percentage\" use=\"optional\" default=\"50%\"/>\n    <xsd:attribute name=\"firstSlideNum\" type=\"xsd:int\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"showSpecialPlsOnTitleSld\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rtl\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removePersonalInfoOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"compatMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"strictFirstAndLastChars\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"embedTrueTypeFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveSubsetFonts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"bookmarkIdSeed\" type=\"ST_BookmarkIdSeed\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:element name=\"presentation\" type=\"CT_Presentation\"/>\n  <xsd:complexType name=\"CT_HtmlPublishProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showSpeakerNotes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebColorType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"browser\"/>\n      <xsd:enumeration value=\"presentationText\"/>\n      <xsd:enumeration value=\"presentationAccent\"/>\n      <xsd:enumeration value=\"whiteTextOnBlack\"/>\n      <xsd:enumeration value=\"blackTextOnWhite\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebScreenSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1400\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WebEncoding\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"resizeGraphics\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"relyOnVml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"organizeInFolders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useLongFilenames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"imgSz\" type=\"ST_WebScreenSize\" use=\"optional\" default=\"800x600\"/>\n    <xsd:attribute name=\"encoding\" type=\"ST_WebEncoding\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"clr\" type=\"ST_WebColorType\" use=\"optional\" default=\"whiteTextOnBlack\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintWhat\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"slides\"/>\n      <xsd:enumeration value=\"handouts1\"/>\n      <xsd:enumeration value=\"handouts2\"/>\n      <xsd:enumeration value=\"handouts3\"/>\n      <xsd:enumeration value=\"handouts4\"/>\n      <xsd:enumeration value=\"handouts6\"/>\n      <xsd:enumeration value=\"handouts9\"/>\n      <xsd:enumeration value=\"notes\"/>\n      <xsd:enumeration value=\"outline\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PrintColorMode\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"bw\"/>\n      <xsd:enumeration value=\"gray\"/>\n      <xsd:enumeration value=\"clr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PrintProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prnWhat\" type=\"ST_PrintWhat\" use=\"optional\" default=\"slides\"/>\n    <xsd:attribute name=\"clrMode\" type=\"ST_PrintColorMode\" use=\"optional\" default=\"clr\"/>\n    <xsd:attribute name=\"hiddenSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scaleToFitPaper\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"frameSlides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoBrowse\">\n    <xsd:attribute name=\"showScrollbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShowInfoKiosk\">\n    <xsd:attribute name=\"restart\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"300000\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ShowType\">\n    <xsd:choice>\n      <xsd:element name=\"present\" type=\"CT_Empty\"/>\n      <xsd:element name=\"browse\" type=\"CT_ShowInfoBrowse\"/>\n      <xsd:element name=\"kiosk\" type=\"CT_ShowInfoKiosk\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ShowProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:group ref=\"EG_ShowType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_SlideListChoice\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"penClr\" type=\"a:CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"loop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showNarration\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAnimation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"useTimings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PresentationProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"htmlPubPr\" type=\"CT_HtmlPublishProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPr\" type=\"CT_WebProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"prnPr\" type=\"CT_PrintProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"showPr\" type=\"CT_ShowProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrMru\" type=\"a:CT_ColorMRU\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"presentationPr\" type=\"CT_PresentationProperties\"/>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sldNum\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"hdr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"ftr\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"dt\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PlaceholderType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"body\"/>\n      <xsd:enumeration value=\"ctrTitle\"/>\n      <xsd:enumeration value=\"subTitle\"/>\n      <xsd:enumeration value=\"dt\"/>\n      <xsd:enumeration value=\"sldNum\"/>\n      <xsd:enumeration value=\"ftr\"/>\n      <xsd:enumeration value=\"hdr\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"clipArt\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"media\"/>\n      <xsd:enumeration value=\"sldImg\"/>\n      <xsd:enumeration value=\"pic\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PlaceholderSize\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"full\"/>\n      <xsd:enumeration value=\"half\"/>\n      <xsd:enumeration value=\"quarter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_PlaceholderType\" use=\"optional\" default=\"obj\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"horz\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_PlaceholderSize\" use=\"optional\" default=\"full\"/>\n    <xsd:attribute name=\"idx\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hasCustomPrompt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ApplicationNonVisualDrawingProps\">\n    <xsd:sequence>\n      <xsd:element name=\"ph\" type=\"CT_Placeholder\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_Media\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"isPhoto\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvSpPr\" type=\"a:CT_NonVisualDrawingShapeProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvSpPr\" type=\"CT_ShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txBody\" type=\"a:CT_TextBody\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"useBgFill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConnectorNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvCxnSpPr\" type=\"a:CT_NonVisualConnectorProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connector\">\n    <xsd:sequence>\n      <xsd:element name=\"nvCxnSpPr\" type=\"CT_ConnectorNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PictureNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvPicPr\" type=\"a:CT_NonVisualPictureProperties\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:element name=\"nvPicPr\" type=\"CT_PictureNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"blipFill\" type=\"a:CT_BlipFillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spPr\" type=\"a:CT_ShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"a:CT_ShapeStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrameNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGraphicFramePr\" type=\"a:CT_NonVisualGraphicFrameProperties\"\n        minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GraphicalObjectFrame\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGraphicFramePr\" type=\"CT_GraphicalObjectFrameNonVisual\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"xfrm\" type=\"a:CT_Transform2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"a:graphic\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShapeNonVisual\">\n    <xsd:sequence>\n      <xsd:element name=\"cNvPr\" type=\"a:CT_NonVisualDrawingProps\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cNvGrpSpPr\" type=\"a:CT_NonVisualGroupDrawingShapeProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"nvPr\" type=\"CT_ApplicationNonVisualDrawingProps\" minOccurs=\"1\"\n        maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupShape\">\n    <xsd:sequence>\n      <xsd:element name=\"nvGrpSpPr\" type=\"CT_GroupShapeNonVisual\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"grpSpPr\" type=\"a:CT_GroupShapeProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"sp\" type=\"CT_Shape\"/>\n        <xsd:element name=\"grpSp\" type=\"CT_GroupShape\"/>\n        <xsd:element name=\"graphicFrame\" type=\"CT_GraphicalObjectFrame\"/>\n        <xsd:element name=\"cxnSp\" type=\"CT_Connector\"/>\n        <xsd:element name=\"pic\" type=\"CT_Picture\"/>\n        <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_TopLevelSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMap\" type=\"a:CT_ColorMapping\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_ChildSlide\">\n    <xsd:sequence>\n      <xsd:element name=\"clrMapOvr\" type=\"a:CT_ColorMappingOverride\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_ChildSlide\">\n    <xsd:attribute name=\"showMasterSp\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showMasterPhAnim\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_BackgroundProperties\">\n    <xsd:sequence>\n      <xsd:group ref=\"a:EG_FillProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"a:EG_EffectProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shadeToTitle\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_Background\">\n    <xsd:choice>\n      <xsd:element name=\"bgPr\" type=\"CT_BackgroundProperties\"/>\n      <xsd:element name=\"bgRef\" type=\"a:CT_StyleMatrixReference\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_Background\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"bwMode\" type=\"a:ST_BlackWhiteMode\" use=\"optional\" default=\"white\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideData\">\n    <xsd:sequence>\n      <xsd:element name=\"bg\" type=\"CT_Background\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"spTree\" type=\"CT_GroupShape\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"custDataLst\" type=\"CT_CustomerDataList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_ControlList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Slide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sld\" type=\"CT_Slide\"/>\n  <xsd:simpleType name=\"ST_SlideLayoutType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"title\"/>\n      <xsd:enumeration value=\"tx\"/>\n      <xsd:enumeration value=\"twoColTx\"/>\n      <xsd:enumeration value=\"tbl\"/>\n      <xsd:enumeration value=\"txAndChart\"/>\n      <xsd:enumeration value=\"chartAndTx\"/>\n      <xsd:enumeration value=\"dgm\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"txAndClipArt\"/>\n      <xsd:enumeration value=\"clipArtAndTx\"/>\n      <xsd:enumeration value=\"titleOnly\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"txAndObj\"/>\n      <xsd:enumeration value=\"objAndTx\"/>\n      <xsd:enumeration value=\"objOnly\"/>\n      <xsd:enumeration value=\"obj\"/>\n      <xsd:enumeration value=\"txAndMedia\"/>\n      <xsd:enumeration value=\"mediaAndTx\"/>\n      <xsd:enumeration value=\"objOverTx\"/>\n      <xsd:enumeration value=\"txOverObj\"/>\n      <xsd:enumeration value=\"txAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndTx\"/>\n      <xsd:enumeration value=\"twoObjOverTx\"/>\n      <xsd:enumeration value=\"fourObj\"/>\n      <xsd:enumeration value=\"vertTx\"/>\n      <xsd:enumeration value=\"clipArtAndVertTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTx\"/>\n      <xsd:enumeration value=\"vertTitleAndTxOverChart\"/>\n      <xsd:enumeration value=\"twoObj\"/>\n      <xsd:enumeration value=\"objAndTwoObj\"/>\n      <xsd:enumeration value=\"twoObjAndObj\"/>\n      <xsd:enumeration value=\"cust\"/>\n      <xsd:enumeration value=\"secHead\"/>\n      <xsd:enumeration value=\"twoTxTwoObj\"/>\n      <xsd:enumeration value=\"objTx\"/>\n      <xsd:enumeration value=\"picTx\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayout\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n    <xsd:attribute name=\"matchingName\" type=\"xsd:string\" use=\"optional\" default=\"\"/>\n    <xsd:attribute name=\"type\" type=\"ST_SlideLayoutType\" use=\"optional\" default=\"cust\"/>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userDrawn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldLayout\" type=\"CT_SlideLayout\"/>\n  <xsd:complexType name=\"CT_SlideMasterTextStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"titleStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bodyStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"otherStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SlideLayoutId\">\n    <xsd:restriction base=\"xsd:unsignedInt\">\n      <xsd:minInclusive value=\"2147483648\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SlideLayoutIdListEntry\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_SlideLayoutId\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideLayoutIdList\">\n    <xsd:sequence>\n      <xsd:element name=\"sldLayoutId\" type=\"CT_SlideLayoutIdListEntry\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideMaster\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLayoutIdLst\" type=\"CT_SlideLayoutIdList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"transition\" type=\"CT_SlideTransition\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"timing\" type=\"CT_SlideTiming\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"txStyles\" type=\"CT_SlideMasterTextStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserve\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldMaster\" type=\"CT_SlideMaster\"/>\n  <xsd:complexType name=\"CT_HandoutMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"handoutMaster\" type=\"CT_HandoutMaster\"/>\n  <xsd:complexType name=\"CT_NotesMaster\">\n    <xsd:sequence>\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_TopLevelSlide\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hf\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesStyle\" type=\"a:CT_TextListStyle\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"notesMaster\" type=\"CT_NotesMaster\"/>\n  <xsd:complexType name=\"CT_NotesSlide\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cSld\" type=\"CT_CommonSlideData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ChildSlide\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionListModify\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_ChildSlide\"/>\n  </xsd:complexType>\n  <xsd:element name=\"notes\" type=\"CT_NotesSlide\"/>\n  <xsd:complexType name=\"CT_SlideSyncProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"serverSldId\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"serverSldModifiedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"clientInsertedTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"sldSyncPr\" type=\"CT_SlideSyncProperties\"/>\n  <xsd:complexType name=\"CT_StringTag\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TagList\">\n    <xsd:sequence>\n      <xsd:element name=\"tag\" type=\"CT_StringTag\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"tagLst\" type=\"CT_TagList\"/>\n  <xsd:simpleType name=\"ST_SplitterBarState\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"minimized\"/>\n      <xsd:enumeration value=\"restored\"/>\n      <xsd:enumeration value=\"maximized\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ViewType\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:enumeration value=\"sldView\"/>\n      <xsd:enumeration value=\"sldMasterView\"/>\n      <xsd:enumeration value=\"notesView\"/>\n      <xsd:enumeration value=\"handoutView\"/>\n      <xsd:enumeration value=\"notesMasterView\"/>\n      <xsd:enumeration value=\"outlineView\"/>\n      <xsd:enumeration value=\"sldSorterView\"/>\n      <xsd:enumeration value=\"sldThumbnailView\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NormalViewPortion\">\n    <xsd:attribute name=\"sz\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n    <xsd:attribute name=\"autoAdjust\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NormalViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"restoredLeft\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"restoredTop\" type=\"CT_NormalViewPortion\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showOutlineIcons\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapVertSplitter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"vertBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"horzBarState\" type=\"ST_SplitterBarState\" use=\"optional\" default=\"restored\"/>\n    <xsd:attribute name=\"preferSingleView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"scale\" type=\"a:CT_Scale2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"origin\" type=\"a:CT_Point2D\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"varScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesTextViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideEntry\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"collapse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewSlideList\">\n    <xsd:sequence>\n      <xsd:element name=\"sld\" type=\"CT_OutlineViewSlideEntry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OutlineViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sldLst\" type=\"CT_OutlineViewSlideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideSorterViewProperties\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"showFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guide\">\n    <xsd:attribute name=\"orient\" type=\"ST_Direction\" use=\"optional\" default=\"vert\"/>\n    <xsd:attribute name=\"pos\" type=\"a:ST_Coordinate32\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GuideList\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"guide\" type=\"CT_Guide\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommonSlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cViewPr\" type=\"CT_CommonViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"guideLst\" type=\"CT_GuideList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"snapToGrid\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"snapToObjects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGuides\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SlideViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NotesViewProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"cSldViewPr\" type=\"CT_CommonSlideViewProperties\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ViewProperties\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"normalViewPr\" type=\"CT_NormalViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"slideViewPr\" type=\"CT_SlideViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlineViewPr\" type=\"CT_OutlineViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notesTextViewPr\" type=\"CT_NotesTextViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sorterViewPr\" type=\"CT_SlideSorterViewProperties\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"notesViewPr\" type=\"CT_NotesViewProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpacing\" type=\"a:CT_PositiveSize2D\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastView\" type=\"ST_ViewType\" use=\"optional\" default=\"sldView\"/>\n    <xsd:attribute name=\"showComments\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:element name=\"viewPr\" type=\"CT_ViewProperties\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/characteristics\"\n  elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_AdditionalCharacteristics\">\n    <xsd:sequence>\n      <xsd:element name=\"characteristic\" type=\"CT_Characteristic\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Characteristic\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"relation\" type=\"ST_Relation\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"vocabulary\" type=\"xsd:anyURI\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Relation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ge\"/>\n      <xsd:enumeration value=\"le\"/>\n      <xsd:enumeration value=\"gt\"/>\n      <xsd:enumeration value=\"lt\"/>\n      <xsd:enumeration value=\"eq\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"additionalCharacteristics\" type=\"CT_AdditionalCharacteristics\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"s:ST_String\">\n      <xsd:enumeration value=\"ArticleInAPeriodical\"/>\n      <xsd:enumeration value=\"Book\"/>\n      <xsd:enumeration value=\"BookSection\"/>\n      <xsd:enumeration value=\"JournalArticle\"/>\n      <xsd:enumeration value=\"ConferenceProceedings\"/>\n      <xsd:enumeration value=\"Report\"/>\n      <xsd:enumeration value=\"SoundRecording\"/>\n      <xsd:enumeration value=\"Performance\"/>\n      <xsd:enumeration value=\"Art\"/>\n      <xsd:enumeration value=\"DocumentFromInternetSite\"/>\n      <xsd:enumeration value=\"InternetSite\"/>\n      <xsd:enumeration value=\"Film\"/>\n      <xsd:enumeration value=\"Interview\"/>\n      <xsd:enumeration value=\"Patent\"/>\n      <xsd:enumeration value=\"ElectronicSource\"/>\n      <xsd:enumeration value=\"Case\"/>\n      <xsd:enumeration value=\"Misc\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NameListType\">\n    <xsd:sequence>\n      <xsd:element name=\"Person\" type=\"CT_PersonType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PersonType\">\n    <xsd:sequence>\n      <xsd:element name=\"Last\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"First\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Middle\" type=\"s:ST_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameType\">\n    <xsd:sequence>\n      <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NameOrCorporateType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"NameList\" type=\"CT_NameListType\" minOccurs=\"1\" maxOccurs=\"1\"/>\n        <xsd:element name=\"Corporate\" minOccurs=\"1\" maxOccurs=\"1\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AuthorType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"Artist\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Author\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"BookAuthor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Compiler\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Composer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Conductor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Counsel\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Director\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Editor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewee\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Interviewer\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Inventor\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Performer\" type=\"CT_NameOrCorporateType\"/>\n        <xsd:element name=\"ProducerName\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Translator\" type=\"CT_NameType\"/>\n        <xsd:element name=\"Writer\" type=\"CT_NameType\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SourceType\">\n    <xsd:sequence>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"AbbreviatedCaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"AlbumTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Author\" type=\"CT_AuthorType\"/>\n        <xsd:element name=\"BookTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Broadcaster\" type=\"s:ST_String\"/>\n        <xsd:element name=\"BroadcastTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CaseNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ChapterNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"City\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Comments\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ConferenceName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"CountryRegion\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Court\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Day\" type=\"s:ST_String\"/>\n        <xsd:element name=\"DayAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Department\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Distributor\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Edition\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Guid\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Institution\" type=\"s:ST_String\"/>\n        <xsd:element name=\"InternetSiteTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Issue\" type=\"s:ST_String\"/>\n        <xsd:element name=\"JournalName\" type=\"s:ST_String\"/>\n        <xsd:element name=\"LCID\" type=\"s:ST_Lang\"/>\n        <xsd:element name=\"Medium\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Month\" type=\"s:ST_String\"/>\n        <xsd:element name=\"MonthAccessed\" type=\"s:ST_String\"/>\n        <xsd:element name=\"NumberVolumes\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Pages\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PatentNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PeriodicalTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ProductionCompany\" type=\"s:ST_String\"/>\n        <xsd:element name=\"PublicationTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Publisher\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RecordingNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"RefOrder\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Reporter\" type=\"s:ST_String\"/>\n        <xsd:element name=\"SourceType\" type=\"ST_SourceType\"/>\n        <xsd:element name=\"ShortTitle\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StandardNumber\" type=\"s:ST_String\"/>\n        <xsd:element name=\"StateProvince\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Station\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Tag\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Theater\" type=\"s:ST_String\"/>\n        <xsd:element name=\"ThesisType\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Title\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Type\" type=\"s:ST_String\"/>\n        <xsd:element name=\"URL\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Version\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Volume\" type=\"s:ST_String\"/>\n        <xsd:element name=\"Year\" type=\"s:ST_String\"/>\n        <xsd:element name=\"YearAccessed\" type=\"s:ST_String\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"Sources\" type=\"CT_Sources\"/>\n  <xsd:complexType name=\"CT_Sources\">\n    <xsd:sequence>\n      <xsd:element name=\"Source\" type=\"CT_SourceType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectedStyle\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"StyleName\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"URI\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\">\n  <xsd:simpleType name=\"ST_Lang\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColorRGB\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"3\" fixed=\"true\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Panose\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"10\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalendarType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gregorian\"/>\n      <xsd:enumeration value=\"gregorianUs\"/>\n      <xsd:enumeration value=\"gregorianMeFrench\"/>\n      <xsd:enumeration value=\"gregorianArabic\"/>\n      <xsd:enumeration value=\"hijri\"/>\n      <xsd:enumeration value=\"hebrew\"/>\n      <xsd:enumeration value=\"taiwan\"/>\n      <xsd:enumeration value=\"japan\"/>\n      <xsd:enumeration value=\"thai\"/>\n      <xsd:enumeration value=\"korea\"/>\n      <xsd:enumeration value=\"saka\"/>\n      <xsd:enumeration value=\"gregorianXlitEnglish\"/>\n      <xsd:enumeration value=\"gregorianXlitFrench\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hash\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CryptProv\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rsaAES\"/>\n      <xsd:enumeration value=\"rsaFull\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AlgType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"typeAny\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Guid\">\n    <xsd:restriction base=\"xsd:token\">\n      <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff\">\n    <xsd:union memberTypes=\"xsd:boolean ST_OnOff1\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OnOff1\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_String\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XmlName\">\n    <xsd:restriction base=\"xsd:NCName\">\n      <xsd:minLength value=\"1\"/>\n      <xsd:maxLength value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalse\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TrueFalseBlank\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"false\"/>\n      <xsd:enumeration value=\"\"/>\n      <xsd:enumeration value=\"True\"/>\n      <xsd:enumeration value=\"False\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedDecimalNumber\">\n    <xsd:restriction base=\"xsd:decimal\">\n      <xsd:minInclusive value=\"0\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TwipsMeasure\">\n    <xsd:union memberTypes=\"ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignRun\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"superscript\"/>\n      <xsd:enumeration value=\"subscript\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Xstring\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_XAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_YAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"inline\"/>\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"inside\"/>\n      <xsd:enumeration value=\"outside\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConformanceClass\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"strict\"/>\n      <xsd:enumeration value=\"transitional\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UniversalMeasure\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveUniversalMeasure\">\n    <xsd:restriction base=\"ST_UniversalMeasure\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?(mm|cm|in|pt|pc|pi)\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Percentage\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"-?[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"-?((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositivePercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"[0-9]+(\\.[0-9]+)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PositiveFixedPercentage\">\n    <xsd:restriction base=\"ST_Percentage\">\n      <xsd:pattern value=\"((100)|([0-9][0-9]?))(\\.[0-9][0-9]?)?%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/customXml\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:complexType name=\"CT_DatastoreSchemaRef\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreSchemaRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRef\" type=\"CT_DatastoreSchemaRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DatastoreItem\">\n    <xsd:sequence>\n      <xsd:element name=\"schemaRefs\" type=\"CT_DatastoreSchemaRefs\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"itemID\" type=\"s:ST_Guid\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"datastoreItem\" type=\"CT_DatastoreItem\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  targetNamespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">\n  <xsd:complexType name=\"CT_Schema\">\n    <xsd:attribute name=\"uri\" type=\"xsd:string\" default=\"\"/>\n    <xsd:attribute name=\"manifestLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLocation\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"schemaLanguage\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SchemaLibrary\">\n    <xsd:sequence>\n      <xsd:element name=\"schema\" type=\"CT_Schema\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"schemaLibrary\" type=\"CT_SchemaLibrary\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:sequence>\n      <xsd:element name=\"property\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Property\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Property\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n      <xsd:element ref=\"vt:array\"/>\n      <xsd:element ref=\"vt:blob\"/>\n      <xsd:element ref=\"vt:oblob\"/>\n      <xsd:element ref=\"vt:empty\"/>\n      <xsd:element ref=\"vt:null\"/>\n      <xsd:element ref=\"vt:i1\"/>\n      <xsd:element ref=\"vt:i2\"/>\n      <xsd:element ref=\"vt:i4\"/>\n      <xsd:element ref=\"vt:i8\"/>\n      <xsd:element ref=\"vt:int\"/>\n      <xsd:element ref=\"vt:ui1\"/>\n      <xsd:element ref=\"vt:ui2\"/>\n      <xsd:element ref=\"vt:ui4\"/>\n      <xsd:element ref=\"vt:ui8\"/>\n      <xsd:element ref=\"vt:uint\"/>\n      <xsd:element ref=\"vt:r4\"/>\n      <xsd:element ref=\"vt:r8\"/>\n      <xsd:element ref=\"vt:decimal\"/>\n      <xsd:element ref=\"vt:lpstr\"/>\n      <xsd:element ref=\"vt:lpwstr\"/>\n      <xsd:element ref=\"vt:bstr\"/>\n      <xsd:element ref=\"vt:date\"/>\n      <xsd:element ref=\"vt:filetime\"/>\n      <xsd:element ref=\"vt:bool\"/>\n      <xsd:element ref=\"vt:cy\"/>\n      <xsd:element ref=\"vt:error\"/>\n      <xsd:element ref=\"vt:stream\"/>\n      <xsd:element ref=\"vt:ostream\"/>\n      <xsd:element ref=\"vt:storage\"/>\n      <xsd:element ref=\"vt:ostorage\"/>\n      <xsd:element ref=\"vt:vstream\"/>\n      <xsd:element ref=\"vt:clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fmtid\" use=\"required\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"pid\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"linkTarget\" use=\"optional\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"\n  elementFormDefault=\"qualified\" blockDefault=\"#all\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n    schemaLocation=\"shared-documentPropertiesVariantTypes.xsd\"/>\n  <xsd:element name=\"Properties\" type=\"CT_Properties\"/>\n  <xsd:complexType name=\"CT_Properties\">\n    <xsd:all>\n      <xsd:element name=\"Template\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Manager\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Company\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Pages\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Words\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Characters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"PresentationFormat\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"Lines\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Paragraphs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Slides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"Notes\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"TotalTime\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"HiddenSlides\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"MMClips\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"ScaleCrop\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HeadingPairs\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"TitlesOfParts\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorLpstr\"/>\n      <xsd:element name=\"LinksUpToDate\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"CharactersWithSpaces\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n      <xsd:element name=\"SharedDoc\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"HyperlinkBase\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"HLinks\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_VectorVariant\"/>\n      <xsd:element name=\"HyperlinksChanged\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:boolean\"/>\n      <xsd:element name=\"DigSig\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DigSigBlob\"/>\n      <xsd:element name=\"Application\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"AppVersion\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:string\"/>\n      <xsd:element name=\"DocSecurity\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xsd:int\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorVariant\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VectorLpstr\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:vector\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DigSigBlob\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"vt:blob\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"\n  blockDefault=\"#all\" elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:simpleType name=\"ST_VectorBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"i8\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"ui8\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"lpstr\"/>\n      <xsd:enumeration value=\"lpwstr\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"filetime\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n      <xsd:enumeration value=\"clsid\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ArrayBaseType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"variant\"/>\n      <xsd:enumeration value=\"i1\"/>\n      <xsd:enumeration value=\"i2\"/>\n      <xsd:enumeration value=\"i4\"/>\n      <xsd:enumeration value=\"int\"/>\n      <xsd:enumeration value=\"ui1\"/>\n      <xsd:enumeration value=\"ui2\"/>\n      <xsd:enumeration value=\"ui4\"/>\n      <xsd:enumeration value=\"uint\"/>\n      <xsd:enumeration value=\"r4\"/>\n      <xsd:enumeration value=\"r8\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bstr\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"bool\"/>\n      <xsd:enumeration value=\"cy\"/>\n      <xsd:enumeration value=\"error\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Cy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*[0-9]*\\.[0-9]{4}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Error\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"\\s*0x[0-9A-Za-z]{8}\\s*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Null\"/>\n  <xsd:complexType name=\"CT_Vector\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"baseType\" type=\"ST_VectorBaseType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Array\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"cy\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"lBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"uBounds\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"baseType\" type=\"ST_ArrayBaseType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Variant\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element ref=\"variant\"/>\n      <xsd:element ref=\"vector\"/>\n      <xsd:element ref=\"array\"/>\n      <xsd:element ref=\"blob\"/>\n      <xsd:element ref=\"oblob\"/>\n      <xsd:element ref=\"empty\"/>\n      <xsd:element ref=\"null\"/>\n      <xsd:element ref=\"i1\"/>\n      <xsd:element ref=\"i2\"/>\n      <xsd:element ref=\"i4\"/>\n      <xsd:element ref=\"i8\"/>\n      <xsd:element ref=\"int\"/>\n      <xsd:element ref=\"ui1\"/>\n      <xsd:element ref=\"ui2\"/>\n      <xsd:element ref=\"ui4\"/>\n      <xsd:element ref=\"ui8\"/>\n      <xsd:element ref=\"uint\"/>\n      <xsd:element ref=\"r4\"/>\n      <xsd:element ref=\"r8\"/>\n      <xsd:element ref=\"decimal\"/>\n      <xsd:element ref=\"lpstr\"/>\n      <xsd:element ref=\"lpwstr\"/>\n      <xsd:element ref=\"bstr\"/>\n      <xsd:element ref=\"date\"/>\n      <xsd:element ref=\"filetime\"/>\n      <xsd:element ref=\"bool\"/>\n      <xsd:element ref=\"cy\"/>\n      <xsd:element ref=\"error\"/>\n      <xsd:element ref=\"stream\"/>\n      <xsd:element ref=\"ostream\"/>\n      <xsd:element ref=\"storage\"/>\n      <xsd:element ref=\"ostorage\"/>\n      <xsd:element ref=\"vstream\"/>\n      <xsd:element ref=\"clsid\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Vstream\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:base64Binary\">\n        <xsd:attribute name=\"version\" type=\"s:ST_Guid\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:element name=\"variant\" type=\"CT_Variant\"/>\n  <xsd:element name=\"vector\" type=\"CT_Vector\"/>\n  <xsd:element name=\"array\" type=\"CT_Array\"/>\n  <xsd:element name=\"blob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"oblob\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"empty\" type=\"CT_Empty\"/>\n  <xsd:element name=\"null\" type=\"CT_Null\"/>\n  <xsd:element name=\"i1\" type=\"xsd:byte\"/>\n  <xsd:element name=\"i2\" type=\"xsd:short\"/>\n  <xsd:element name=\"i4\" type=\"xsd:int\"/>\n  <xsd:element name=\"i8\" type=\"xsd:long\"/>\n  <xsd:element name=\"int\" type=\"xsd:int\"/>\n  <xsd:element name=\"ui1\" type=\"xsd:unsignedByte\"/>\n  <xsd:element name=\"ui2\" type=\"xsd:unsignedShort\"/>\n  <xsd:element name=\"ui4\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"ui8\" type=\"xsd:unsignedLong\"/>\n  <xsd:element name=\"uint\" type=\"xsd:unsignedInt\"/>\n  <xsd:element name=\"r4\" type=\"xsd:float\"/>\n  <xsd:element name=\"r8\" type=\"xsd:double\"/>\n  <xsd:element name=\"decimal\" type=\"xsd:decimal\"/>\n  <xsd:element name=\"lpstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"lpwstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"bstr\" type=\"xsd:string\"/>\n  <xsd:element name=\"date\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"filetime\" type=\"xsd:dateTime\"/>\n  <xsd:element name=\"bool\" type=\"xsd:boolean\"/>\n  <xsd:element name=\"cy\" type=\"ST_Cy\"/>\n  <xsd:element name=\"error\" type=\"ST_Error\"/>\n  <xsd:element name=\"stream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostream\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"storage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"ostorage\" type=\"xsd:base64Binary\"/>\n  <xsd:element name=\"vstream\" type=\"CT_Vstream\"/>\n  <xsd:element name=\"clsid\" type=\"s:ST_Guid\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" schemaLocation=\"xml.xsd\"/>\n  <xsd:simpleType name=\"ST_Integer255\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"1\"/>\n      <xsd:maxInclusive value=\"255\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer255\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer255\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Integer2\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"-2\"/>\n      <xsd:maxInclusive value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Integer2\">\n    <xsd:attribute name=\"val\" type=\"ST_Integer2\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SpacingRule\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SpacingRule\">\n    <xsd:attribute name=\"val\" type=\"ST_SpacingRule\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnSignedInteger\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnSignedInteger\">\n    <xsd:attribute name=\"val\" type=\"ST_UnSignedInteger\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Char\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Char\">\n    <xsd:attribute name=\"val\" type=\"ST_Char\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_XAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_YAlign\">\n    <xsd:attribute name=\"val\" type=\"s:ST_YAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"centered\"/>\n      <xsd:enumeration value=\"match\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shp\">\n    <xsd:attribute name=\"val\" type=\"ST_Shp\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"skw\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"noBar\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FType\">\n    <xsd:attribute name=\"val\" type=\"ST_FType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LimLoc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"undOvr\"/>\n      <xsd:enumeration value=\"subSup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LimLoc\">\n    <xsd:attribute name=\"val\" type=\"ST_LimLoc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TopBot\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"bot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TopBot\">\n    <xsd:attribute name=\"val\" type=\"ST_TopBot\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Script\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"fraktur\"/>\n      <xsd:enumeration value=\"double-struck\"/>\n      <xsd:enumeration value=\"sans-serif\"/>\n      <xsd:enumeration value=\"monospace\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Script\">\n    <xsd:attribute name=\"val\" type=\"ST_Script\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Style\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"i\"/>\n      <xsd:enumeration value=\"bi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:attribute name=\"val\" type=\"ST_Style\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ManualBreak\">\n    <xsd:attribute name=\"alnAt\" type=\"ST_Integer255\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ScriptStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"scr\" minOccurs=\"0\" type=\"CT_Script\"/>\n      <xsd:element name=\"sty\" minOccurs=\"0\" type=\"CT_Style\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPR\">\n    <xsd:sequence>\n      <xsd:element name=\"lit\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n      <xsd:choice>\n        <xsd:element name=\"nor\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n        <xsd:sequence>\n          <xsd:group ref=\"EG_ScriptStyle\"/>\n        </xsd:sequence>\n      </xsd:choice>\n      <xsd:element name=\"brk\" minOccurs=\"0\" type=\"CT_ManualBreak\"/>\n      <xsd:element name=\"aln\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPR\" minOccurs=\"0\"/>\n      <xsd:group ref=\"w:EG_RPr\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:group ref=\"w:EG_RunInnerContent\"/>\n        <xsd:element name=\"t\" type=\"CT_Text\" minOccurs=\"0\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CtrlPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"w:EG_RPrMath\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AccPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Acc\">\n    <xsd:sequence>\n      <xsd:element name=\"accPr\" type=\"CT_AccPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BarPr\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bar\">\n    <xsd:sequence>\n      <xsd:element name=\"barPr\" type=\"CT_BarPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"opEmu\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBreak\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"diff\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"brk\" type=\"CT_ManualBreak\" minOccurs=\"0\"/>\n      <xsd:element name=\"aln\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Box\">\n    <xsd:sequence>\n      <xsd:element name=\"boxPr\" type=\"CT_BoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBoxPr\">\n    <xsd:sequence>\n      <xsd:element name=\"hideTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideBot\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideLeft\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideRight\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeH\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeV\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeBLTR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strikeTLBR\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderBox\">\n    <xsd:sequence>\n      <xsd:element name=\"borderBoxPr\" type=\"CT_BorderBoxPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DPr\">\n    <xsd:sequence>\n      <xsd:element name=\"begChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"sepChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"endChr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shp\" type=\"CT_Shp\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_D\">\n    <xsd:sequence>\n      <xsd:element name=\"dPr\" type=\"CT_DPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"objDist\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EqArr\">\n    <xsd:sequence>\n      <xsd:element name=\"eqArrPr\" type=\"CT_EqArrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FPr\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FType\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:sequence>\n      <xsd:element name=\"fPr\" type=\"CT_FPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"num\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"den\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FuncPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Func\">\n    <xsd:sequence>\n      <xsd:element name=\"funcPr\" type=\"CT_FuncPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"fName\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChrPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"pos\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"vertJc\" type=\"CT_TopBot\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupChr\">\n    <xsd:sequence>\n      <xsd:element name=\"groupChrPr\" type=\"CT_GroupChrPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLowPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimLow\">\n    <xsd:sequence>\n      <xsd:element name=\"limLowPr\" type=\"CT_LimLowPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUppPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LimUpp\">\n    <xsd:sequence>\n      <xsd:element name=\"limUppPr\" type=\"CT_LimUppPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"lim\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCPr\">\n    <xsd:sequence>\n      <xsd:element name=\"count\" type=\"CT_Integer255\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcJc\" type=\"CT_XAlign\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MC\">\n    <xsd:sequence>\n      <xsd:element name=\"mcPr\" type=\"CT_MCPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MCS\">\n    <xsd:sequence>\n      <xsd:element name=\"mc\" type=\"CT_MC\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MPr\">\n    <xsd:sequence>\n      <xsd:element name=\"baseJc\" type=\"CT_YAlign\" minOccurs=\"0\"/>\n      <xsd:element name=\"plcHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGpRule\" type=\"CT_SpacingRule\" minOccurs=\"0\"/>\n      <xsd:element name=\"rSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cSp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"cGp\" type=\"CT_UnSignedInteger\" minOccurs=\"0\"/>\n      <xsd:element name=\"mcs\" type=\"CT_MCS\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MR\">\n    <xsd:sequence>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_M\">\n    <xsd:sequence>\n      <xsd:element name=\"mPr\" type=\"CT_MPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"mr\" type=\"CT_MR\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NaryPr\">\n    <xsd:sequence>\n      <xsd:element name=\"chr\" type=\"CT_Char\" minOccurs=\"0\"/>\n      <xsd:element name=\"limLoc\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"grow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"supHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Nary\">\n    <xsd:sequence>\n      <xsd:element name=\"naryPr\" type=\"CT_NaryPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhantPr\">\n    <xsd:sequence>\n      <xsd:element name=\"show\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroWid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroAsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"zeroDesc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"transp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Phant\">\n    <xsd:sequence>\n      <xsd:element name=\"phantPr\" type=\"CT_PhantPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RadPr\">\n    <xsd:sequence>\n      <xsd:element name=\"degHide\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rad\">\n    <xsd:sequence>\n      <xsd:element name=\"radPr\" type=\"CT_RadPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"deg\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPrePr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SPre\">\n    <xsd:sequence>\n      <xsd:element name=\"sPrePr\" type=\"CT_SPrePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSub\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubPr\" type=\"CT_SSubPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"alnScr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSubSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSubSupPr\" type=\"CT_SSubSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sub\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSupPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SSup\">\n    <xsd:sequence>\n      <xsd:element name=\"sSupPr\" type=\"CT_SSupPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"e\" type=\"CT_OMathArg\"/>\n      <xsd:element name=\"sup\" type=\"CT_OMathArg\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_OMathMathElements\">\n    <xsd:choice>\n      <xsd:element name=\"acc\" type=\"CT_Acc\"/>\n      <xsd:element name=\"bar\" type=\"CT_Bar\"/>\n      <xsd:element name=\"box\" type=\"CT_Box\"/>\n      <xsd:element name=\"borderBox\" type=\"CT_BorderBox\"/>\n      <xsd:element name=\"d\" type=\"CT_D\"/>\n      <xsd:element name=\"eqArr\" type=\"CT_EqArr\"/>\n      <xsd:element name=\"f\" type=\"CT_F\"/>\n      <xsd:element name=\"func\" type=\"CT_Func\"/>\n      <xsd:element name=\"groupChr\" type=\"CT_GroupChr\"/>\n      <xsd:element name=\"limLow\" type=\"CT_LimLow\"/>\n      <xsd:element name=\"limUpp\" type=\"CT_LimUpp\"/>\n      <xsd:element name=\"m\" type=\"CT_M\"/>\n      <xsd:element name=\"nary\" type=\"CT_Nary\"/>\n      <xsd:element name=\"phant\" type=\"CT_Phant\"/>\n      <xsd:element name=\"rad\" type=\"CT_Rad\"/>\n      <xsd:element name=\"sPre\" type=\"CT_SPre\"/>\n      <xsd:element name=\"sSub\" type=\"CT_SSub\"/>\n      <xsd:element name=\"sSubSup\" type=\"CT_SSubSup\"/>\n      <xsd:element name=\"sSup\" type=\"CT_SSup\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_OMathElements\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_OMathMathElements\"/>\n      <xsd:group ref=\"w:EG_PContentMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_OMathArgPr\">\n    <xsd:sequence>\n      <xsd:element name=\"argSz\" type=\"CT_Integer2\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathArg\">\n    <xsd:sequence>\n      <xsd:element name=\"argPr\" type=\"CT_OMathArgPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ctrlPr\" type=\"CT_CtrlPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"centerGroup\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OMathJc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMathParaPr\">\n    <xsd:sequence>\n      <xsd:element name=\"jc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBin\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"before\"/>\n      <xsd:enumeration value=\"after\"/>\n      <xsd:enumeration value=\"repeat\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBin\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBin\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BreakBinSub\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"--\"/>\n      <xsd:enumeration value=\"-+\"/>\n      <xsd:enumeration value=\"+-\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BreakBinSub\">\n    <xsd:attribute name=\"val\" type=\"ST_BreakBinSub\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathPr\">\n    <xsd:sequence>\n      <xsd:element name=\"mathFont\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBin\" type=\"CT_BreakBin\" minOccurs=\"0\"/>\n      <xsd:element name=\"brkBinSub\" type=\"CT_BreakBinSub\" minOccurs=\"0\"/>\n      <xsd:element name=\"smallFrac\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dispDef\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"rMargin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"defJc\" type=\"CT_OMathJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"preSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"postSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"interSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"intraSp\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"wrapIndent\" type=\"CT_TwipsMeasure\"/>\n        <xsd:element name=\"wrapRight\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"intLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n      <xsd:element name=\"naryLim\" type=\"CT_LimLoc\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"mathPr\" type=\"CT_MathPr\"/>\n  <xsd:complexType name=\"CT_OMathPara\">\n    <xsd:sequence>\n      <xsd:element name=\"oMathParaPr\" type=\"CT_OMathParaPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OMath\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OMath\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_OMathElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"oMathPara\" type=\"CT_OMathPara\"/>\n  <xsd:element name=\"oMath\" type=\"CT_OMath\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  elementFormDefault=\"qualified\"\n  targetNamespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  blockDefault=\"#all\">\n  <xsd:simpleType name=\"ST_RelationshipId\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:attribute name=\"id\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"embed\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"link\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"dm\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"lo\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"qs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"cs\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"blip\" type=\"ST_RelationshipId\" default=\"\"/>\n  <xsd:attribute name=\"pict\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"href\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"topRight\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomLeft\" type=\"ST_RelationshipId\"/>\n  <xsd:attribute name=\"bottomRight\" type=\"ST_RelationshipId\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"\n  elementFormDefault=\"qualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import \n    namespace=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"\n    schemaLocation=\"dml-spreadsheetDrawing.xsd\"/>\n  <xsd:complexType name=\"CT_AutoFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"filterColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FilterColumn\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FilterColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"filters\" type=\"CT_Filters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"top10\" type=\"CT_Top10\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customFilters\" type=\"CT_CustomFilters\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dynamicFilter\" type=\"CT_DynamicFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colorFilter\" type=\"CT_ColorFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconFilter\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_IconFilter\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"colId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"hiddenButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showButton\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" type=\"CT_Filter\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dateGroupItem\" type=\"CT_DateGroupItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n    <xsd:attribute name=\"blank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calendarType\" type=\"s:ST_CalendarType\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Filter\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"customFilter\" type=\"CT_CustomFilter\" minOccurs=\"1\" maxOccurs=\"2\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"and\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomFilter\">\n    <xsd:attribute name=\"operator\" type=\"ST_FilterOperator\" default=\"equal\" use=\"optional\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Top10\">\n    <xsd:attribute name=\"top\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"filterVal\" type=\"xsd:double\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorFilter\">\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"cellColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconFilter\">\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"required\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FilterOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DynamicFilter\">\n    <xsd:attribute name=\"type\" type=\"ST_DynamicFilterType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"valIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxVal\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DynamicFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n      <xsd:enumeration value=\"belowAverage\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_IconSetType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"3Arrows\"/>\n      <xsd:enumeration value=\"3ArrowsGray\"/>\n      <xsd:enumeration value=\"3Flags\"/>\n      <xsd:enumeration value=\"3TrafficLights1\"/>\n      <xsd:enumeration value=\"3TrafficLights2\"/>\n      <xsd:enumeration value=\"3Signs\"/>\n      <xsd:enumeration value=\"3Symbols\"/>\n      <xsd:enumeration value=\"3Symbols2\"/>\n      <xsd:enumeration value=\"4Arrows\"/>\n      <xsd:enumeration value=\"4ArrowsGray\"/>\n      <xsd:enumeration value=\"4RedToBlack\"/>\n      <xsd:enumeration value=\"4Rating\"/>\n      <xsd:enumeration value=\"4TrafficLights\"/>\n      <xsd:enumeration value=\"5Arrows\"/>\n      <xsd:enumeration value=\"5ArrowsGray\"/>\n      <xsd:enumeration value=\"5Rating\"/>\n      <xsd:enumeration value=\"5Quarters\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SortState\">\n    <xsd:sequence>\n      <xsd:element name=\"sortCondition\" minOccurs=\"0\" maxOccurs=\"64\" type=\"CT_SortCondition\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"columnSort\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"caseSensitive\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortMethod\" type=\"ST_SortMethod\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SortCondition\">\n    <xsd:attribute name=\"descending\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sortBy\" type=\"ST_SortBy\" use=\"optional\" default=\"value\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"customList\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3Arrows\"/>\n    <xsd:attribute name=\"iconId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cellColor\"/>\n      <xsd:enumeration value=\"fontColor\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_SortMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stroke\"/>\n      <xsd:enumeration value=\"pinYin\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DateGroupItem\">\n    <xsd:attribute name=\"year\" type=\"xsd:unsignedShort\" use=\"required\"/>\n    <xsd:attribute name=\"month\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"day\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"hour\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"minute\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"second\" type=\"xsd:unsignedShort\" use=\"optional\"/>\n    <xsd:attribute name=\"dateTimeGrouping\" type=\"ST_DateTimeGrouping\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTimeGrouping\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"year\"/>\n      <xsd:enumeration value=\"month\"/>\n      <xsd:enumeration value=\"day\"/>\n      <xsd:enumeration value=\"hour\"/>\n      <xsd:enumeration value=\"minute\"/>\n      <xsd:enumeration value=\"second\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellRef\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Ref\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefA\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Sqref\">\n    <xsd:list itemType=\"ST_Ref\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Formula\">\n    <xsd:restriction base=\"s:ST_Xstring\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedIntHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnsignedShortHex\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XStringElement\">\n    <xsd:attribute name=\"v\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extension\">\n    <xsd:sequence>\n      <xsd:any processContents=\"lax\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectAnchor\">\n    <xsd:sequence>\n      <xsd:element ref=\"xdr:from\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element ref=\"xdr:to\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"moveWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sizeWithCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ExtensionList\">\n    <xsd:sequence>\n      <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_ExtensionList\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"calcChain\" type=\"CT_CalcChain\"/>\n  <xsd:complexType name=\"CT_CalcChain\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_CalcCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcCell\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"l\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"t\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"a\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"authors\" type=\"CT_Authors\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentList\" type=\"CT_CommentList\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Authors\">\n    <xsd:sequence>\n      <xsd:element name=\"author\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentList\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:sequence>\n      <xsd:element name=\"text\" type=\"CT_Rst\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"commentPr\" type=\"CT_CommentPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"authorId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CommentPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"textHAlign\" type=\"ST_TextHAlign\" use=\"optional\" default=\"left\"/>\n    <xsd:attribute name=\"textVAlign\" type=\"ST_TextVAlign\" use=\"optional\" default=\"top\"/>\n    <xsd:attribute name=\"lockText\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"justLastX\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoScale\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextHAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextVAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"MapInfo\" type=\"CT_MapInfo\"/>\n  <xsd:complexType name=\"CT_MapInfo\">\n    <xsd:sequence>\n      <xsd:element name=\"Schema\" type=\"CT_Schema\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"Map\" type=\"CT_Map\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"SelectionNamespaces\" type=\"xsd:string\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Schema\" mixed=\"true\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaRef\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"Namespace\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"SchemaLanguage\" type=\"xsd:token\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Map\">\n    <xsd:sequence>\n      <xsd:element name=\"DataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ID\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"Name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"RootElement\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"SchemaID\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"ShowImportExportValidationErrors\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"AutoFit\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"Append\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveSortAFLayout\" type=\"xsd:boolean\" use=\"required\"/>\n    <xsd:attribute name=\"PreserveFormat\" type=\"xsd:boolean\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:sequence>\n      <xsd:any/>\n    </xsd:sequence>\n    <xsd:attribute name=\"DataBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBinding\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"ConnectionID\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"FileBindingName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DataBindingLoadMode\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"connections\" type=\"CT_Connections\"/>\n  <xsd:complexType name=\"CT_Connections\">\n    <xsd:sequence>\n      <xsd:element name=\"connection\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Connection\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Connection\">\n    <xsd:sequence>\n      <xsd:element name=\"dbPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_DbPr\"/>\n      <xsd:element name=\"olapPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_OlapPr\"/>\n      <xsd:element name=\"webPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_WebPr\"/>\n      <xsd:element name=\"textPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextPr\"/>\n      <xsd:element name=\"parameters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Parameters\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"odcFile\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"keepAlive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"interval\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"reconnectionMethod\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"refreshedVersion\" use=\"required\" type=\"xsd:unsignedByte\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" use=\"optional\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"savePassword\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"new\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"deleted\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"onlyUseConnectionFile\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"background\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"credentials\" use=\"optional\" type=\"ST_CredMethod\" default=\"integrated\"/>\n    <xsd:attribute name=\"singleSignOnId\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CredMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"integrated\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"stored\"/>\n      <xsd:enumeration value=\"prompt\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DbPr\">\n    <xsd:attribute name=\"connection\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"command\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"serverCommand\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"commandType\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"2\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OlapPr\">\n    <xsd:attribute name=\"local\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"localConnection\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"localRefresh\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sendLocale\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowDrillCount\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"serverFill\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverNumberFormat\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFont\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"serverFontColor\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tables\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Tables\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"xml\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sourceData\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parsePre\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl97\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"textDates\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xl2000\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"url\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"post\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"htmlTables\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"htmlFormat\" use=\"optional\" type=\"ST_HtmlFmt\" default=\"none\"/>\n    <xsd:attribute name=\"editPage\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HtmlFmt\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rtf\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Parameters\">\n    <xsd:sequence>\n      <xsd:element name=\"parameter\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_Parameter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Parameter\">\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sqlType\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"parameterType\" use=\"optional\" type=\"ST_ParameterType\" default=\"prompt\"/>\n    <xsd:attribute name=\"refreshOnChange\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"boolean\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"double\" use=\"optional\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"integer\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"string\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cell\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ParameterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"prompt\"/>\n      <xsd:enumeration value=\"value\"/>\n      <xsd:enumeration value=\"cell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Tables\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_TableMissing\"/>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableMissing\"/>\n  <xsd:complexType name=\"CT_TextPr\">\n    <xsd:sequence>\n      <xsd:element name=\"textFields\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_TextFields\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"prompt\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fileType\" use=\"optional\" type=\"ST_FileType\" default=\"win\"/>\n    <xsd:attribute name=\"codePage\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1252\"/>\n    <xsd:attribute name=\"characterSet\" use=\"optional\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"firstRow\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"sourceFile\" use=\"optional\" type=\"s:ST_Xstring\" default=\"\"/>\n    <xsd:attribute name=\"delimited\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"decimal\" use=\"optional\" type=\"s:ST_Xstring\" default=\".\"/>\n    <xsd:attribute name=\"thousands\" use=\"optional\" type=\"s:ST_Xstring\" default=\",\"/>\n    <xsd:attribute name=\"tab\" use=\"optional\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"space\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"comma\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"semicolon\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"consecutive\" use=\"optional\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"qualifier\" use=\"optional\" type=\"ST_Qualifier\" default=\"doubleQuote\"/>\n    <xsd:attribute name=\"delimiter\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FileType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"mac\"/>\n      <xsd:enumeration value=\"win\"/>\n      <xsd:enumeration value=\"dos\"/>\n      <xsd:enumeration value=\"lin\"/>\n      <xsd:enumeration value=\"other\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Qualifier\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doubleQuote\"/>\n      <xsd:enumeration value=\"singleQuote\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextFields\">\n    <xsd:sequence>\n      <xsd:element name=\"textField\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_TextField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextField\">\n    <xsd:attribute name=\"type\" use=\"optional\" type=\"ST_ExternalConnectionType\" default=\"general\"/>\n    <xsd:attribute name=\"position\" use=\"optional\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ExternalConnectionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"MDY\"/>\n      <xsd:enumeration value=\"DMY\"/>\n      <xsd:enumeration value=\"YMD\"/>\n      <xsd:enumeration value=\"MYD\"/>\n      <xsd:enumeration value=\"DYM\"/>\n      <xsd:enumeration value=\"YDM\"/>\n      <xsd:enumeration value=\"skip\"/>\n      <xsd:enumeration value=\"EMD\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"pivotCacheDefinition\" type=\"CT_PivotCacheDefinition\"/>\n  <xsd:element name=\"pivotCacheRecords\" type=\"CT_PivotCacheRecords\"/>\n  <xsd:element name=\"pivotTableDefinition\" type=\"CT_pivotTableDefinition\"/>\n  <xsd:complexType name=\"CT_PivotCacheDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheSource\" type=\"CT_CacheSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheFields\" type=\"CT_CacheFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cacheHierarchies\" minOccurs=\"0\" type=\"CT_CacheHierarchies\"/>\n      <xsd:element name=\"kpis\" minOccurs=\"0\" type=\"CT_PCDKPIs\"/>\n      <xsd:element name=\"tupleCache\" minOccurs=\"0\" type=\"CT_TupleCache\"/>\n      <xsd:element name=\"calculatedItems\" minOccurs=\"0\" type=\"CT_CalculatedItems\"/>\n      <xsd:element name=\"calculatedMembers\" type=\"CT_CalculatedMembers\" minOccurs=\"0\"/>\n      <xsd:element name=\"dimensions\" type=\"CT_Dimensions\" minOccurs=\"0\"/>\n      <xsd:element name=\"measureGroups\" type=\"CT_MeasureGroups\" minOccurs=\"0\"/>\n      <xsd:element name=\"maps\" type=\"CT_MeasureDimensionMaps\" minOccurs=\"0\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"invalid\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveData\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"optimizeMemory\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshedBy\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDate\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"refreshedDateIso\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"backgroundQuery\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingItemsLimit\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"refreshedVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"recordCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"upgradeOnRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tupleCache\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportSubquery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"supportAdvancedDrill\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheFields\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheField\" type=\"CT_CacheField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheField\">\n    <xsd:sequence>\n      <xsd:element name=\"sharedItems\" type=\"CT_SharedItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fieldGroup\" minOccurs=\"0\" type=\"CT_FieldGroup\"/>\n      <xsd:element name=\"mpMap\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"propertyName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueList\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqlType\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"databaseField\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"mappingCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"memberPropertyField\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheSource\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"worksheetSource\" type=\"CT_WorksheetSource\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"consolidation\" type=\"CT_Consolidation\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"type\" type=\"ST_SourceType\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" default=\"0\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"external\"/>\n      <xsd:enumeration value=\"consolidation\"/>\n      <xsd:enumeration value=\"scenario\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorksheetSource\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Consolidation\">\n    <xsd:sequence>\n      <xsd:element name=\"pages\" type=\"CT_Pages\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rangeSets\" type=\"CT_RangeSets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"autoPage\" type=\"xsd:boolean\" default=\"true\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pages\">\n    <xsd:sequence>\n      <xsd:element name=\"page\" type=\"CT_PCDSCPage\" minOccurs=\"1\" maxOccurs=\"4\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSCPage\">\n    <xsd:sequence>\n      <xsd:element name=\"pageItem\" type=\"CT_PageItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSets\">\n    <xsd:sequence>\n      <xsd:element name=\"rangeSet\" type=\"CT_RangeSet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangeSet\">\n    <xsd:attribute name=\"i1\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i2\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i3\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"i4\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedItems\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"s\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"containsSemiMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsNonDate\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsDate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsString\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"containsBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsMixedTypes\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"containsInteger\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"maxValue\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"minDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"maxDate\" type=\"xsd:dateTime\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"longText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Missing\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Number\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Boolean\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Error\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"in\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"un\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DateTime\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"c\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cp\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"rangePr\" minOccurs=\"0\" type=\"CT_RangePr\"/>\n      <xsd:element name=\"discretePr\" minOccurs=\"0\" type=\"CT_DiscretePr\"/>\n      <xsd:element name=\"groupItems\" minOccurs=\"0\" type=\"CT_GroupItems\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"par\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"base\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RangePr\">\n    <xsd:attribute name=\"autoStart\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"autoEnd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"groupBy\" type=\"ST_GroupBy\" default=\"range\"/>\n    <xsd:attribute name=\"startNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"endNum\" type=\"xsd:double\"/>\n    <xsd:attribute name=\"startDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"endDate\" type=\"xsd:dateTime\"/>\n    <xsd:attribute name=\"groupInterval\" type=\"xsd:double\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GroupBy\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"seconds\"/>\n      <xsd:enumeration value=\"minutes\"/>\n      <xsd:enumeration value=\"hours\"/>\n      <xsd:enumeration value=\"days\"/>\n      <xsd:enumeration value=\"months\"/>\n      <xsd:enumeration value=\"quarters\"/>\n      <xsd:enumeration value=\"years\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DiscretePr\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupItems\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCacheRecords\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Record\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Record\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"b\" type=\"CT_Boolean\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n      <xsd:element name=\"d\" type=\"CT_DateTime\"/>\n      <xsd:element name=\"x\" type=\"CT_Index\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPIs\">\n    <xsd:sequence>\n      <xsd:element name=\"kpi\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PCDKPI\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDKPI\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"value\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"goal\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"status\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"trend\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"weight\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"time\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"cacheHierarchy\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CacheHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CacheHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldsUsage\" minOccurs=\"0\" type=\"CT_FieldsUsage\"/>\n      <xsd:element name=\"groupLevels\" minOccurs=\"0\" type=\"CT_GroupLevels\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"parentSet\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iconSet\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"attribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"time\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"keyAttribute\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultMemberUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"allCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"dimensionUniqueName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"displayFolder\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measureGroup\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"measures\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"oneField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"memberValueDatatype\" use=\"optional\" type=\"xsd:unsignedShort\"/>\n    <xsd:attribute name=\"unbalanced\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"unbalancedGroup\" use=\"optional\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldsUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"fieldUsage\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_FieldUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FieldUsage\">\n    <xsd:attribute name=\"x\" use=\"required\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevels\">\n    <xsd:sequence>\n      <xsd:element name=\"groupLevel\" maxOccurs=\"unbounded\" type=\"CT_GroupLevel\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupLevel\">\n    <xsd:sequence>\n      <xsd:element name=\"groups\" minOccurs=\"0\" type=\"CT_Groups\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"user\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customRollUp\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Groups\">\n    <xsd:sequence>\n      <xsd:element name=\"group\" maxOccurs=\"unbounded\" type=\"CT_LevelGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelGroup\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMembers\" type=\"CT_GroupMembers\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueParent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"groupMember\" maxOccurs=\"unbounded\" type=\"CT_GroupMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GroupMember\">\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"group\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TupleCache\">\n    <xsd:sequence>\n      <xsd:element name=\"entries\" minOccurs=\"0\" type=\"CT_PCDSDTCEntries\"/>\n      <xsd:element name=\"sets\" minOccurs=\"0\" type=\"CT_Sets\"/>\n      <xsd:element name=\"queryCache\" minOccurs=\"0\" type=\"CT_QueryCache\"/>\n      <xsd:element name=\"serverFormats\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ServerFormats\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormat\">\n    <xsd:attribute name=\"culture\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"format\" use=\"optional\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ServerFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"serverFormat\" type=\"CT_ServerFormat\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PCDSDTCEntries\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"m\" type=\"CT_Missing\"/>\n      <xsd:element name=\"n\" type=\"CT_Number\"/>\n      <xsd:element name=\"e\" type=\"CT_Error\"/>\n      <xsd:element name=\"s\" type=\"CT_String\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuples\">\n    <xsd:sequence>\n      <xsd:element name=\"tpl\" type=\"CT_Tuple\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tuple\">\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"item\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sets\">\n    <xsd:sequence>\n      <xsd:element name=\"set\" maxOccurs=\"unbounded\" type=\"CT_Set\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Set\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Tuples\"/>\n      <xsd:element name=\"sortByTuple\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"maxRank\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"setDefinition\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_SortType\" default=\"none\"/>\n    <xsd:attribute name=\"queryFailed\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n      <xsd:enumeration value=\"ascendingAlpha\"/>\n      <xsd:enumeration value=\"descendingAlpha\"/>\n      <xsd:enumeration value=\"ascendingNatural\"/>\n      <xsd:enumeration value=\"descendingNatural\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_QueryCache\">\n    <xsd:sequence>\n      <xsd:element name=\"query\" maxOccurs=\"unbounded\" type=\"CT_Query\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Query\">\n    <xsd:sequence>\n      <xsd:element name=\"tpls\" minOccurs=\"0\" type=\"CT_Tuples\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItems\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedItem\" maxOccurs=\"unbounded\" type=\"CT_CalculatedItem\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedItem\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"formula\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMembers\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedMember\" maxOccurs=\"unbounded\" type=\"CT_CalculatedMember\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalculatedMember\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"mdx\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"memberName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"hierarchy\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"parent\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"solveOrder\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"set\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_pivotTableDefinition\">\n    <xsd:sequence>\n      <xsd:element name=\"location\" type=\"CT_Location\"/>\n      <xsd:element name=\"pivotFields\" type=\"CT_PivotFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowFields\" type=\"CT_RowFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"rowItems\" type=\"CT_rowItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"colFields\" type=\"CT_ColFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"colItems\" type=\"CT_colItems\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageFields\" type=\"CT_PageFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataFields\" type=\"CT_DataFields\" minOccurs=\"0\"/>\n      <xsd:element name=\"formats\" type=\"CT_Formats\" minOccurs=\"0\"/>\n      <xsd:element name=\"conditionalFormats\" type=\"CT_ConditionalFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"chartFormats\" type=\"CT_ChartFormats\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotHierarchies\" type=\"CT_PivotHierarchies\" minOccurs=\"0\"/>\n      <xsd:element name=\"pivotTableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotTableStyle\"/>\n      <xsd:element name=\"filters\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PivotFilters\"/>\n      <xsd:element name=\"rowHierarchiesUsage\" type=\"CT_RowHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"colHierarchiesUsage\" type=\"CT_ColHierarchiesUsage\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cacheId\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dataOnRows\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dataPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"dataCaption\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"grandTotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"errorCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showError\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"missingCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showMissing\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"pageStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"pivotTableStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"vacatedStyle\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"tag\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"updatedVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"minRefreshableVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"asteriskTotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showItems\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"editData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"disableFieldList\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showCalcMbrs\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"visualTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showMultipleLabel\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataDropDown\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"printDrill\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showMemberPropertyTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showDataTips\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableWizard\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableDrill\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"enableFieldProperties\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"useAutoFormatting\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"pageWrap\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"pageOverThenDown\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalHiddenItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rowGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"colGrandTotals\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"fieldPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPrintTitles\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mergeItem\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showDropZones\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"createdVersion\" type=\"xsd:unsignedByte\" default=\"0\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" default=\"1\"/>\n    <xsd:attribute name=\"showEmptyRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showEmptyCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showHeaders\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outlineData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"compactData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"gridDropZones\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"immersive\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleFieldFilters\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"chartFormat\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"rowHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"colHeaderCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fieldListSortAscending\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"mdxSubqueries\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"customListSort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Location\">\n    <xsd:attribute name=\"ref\" use=\"required\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"firstHeaderRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataRow\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"firstDataCol\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"rowPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"colPageCount\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotField\" maxOccurs=\"unbounded\" type=\"CT_PivotField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotField\">\n    <xsd:sequence>\n      <xsd:element name=\"items\" minOccurs=\"0\" type=\"CT_Items\"/>\n      <xsd:element name=\"autoSortScope\" minOccurs=\"0\" type=\"CT_AutoSortScope\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"axis\" use=\"optional\" type=\"ST_Axis\"/>\n    <xsd:attribute name=\"dataField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalCaption\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"showDropDowns\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hiddenLevel\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"uniqueMemberProperty\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"compact\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"allDrilled\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"showAll\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"insertBlankRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"serverField\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"insertPageBreak\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"autoShow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"topAutoShow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"hideNewItems\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"measureFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"itemPageCount\" type=\"xsd:unsignedInt\" default=\"10\"/>\n    <xsd:attribute name=\"sortType\" type=\"ST_FieldSortType\" default=\"manual\"/>\n    <xsd:attribute name=\"dataSourceSort\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"nonAutoSortDefault\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"rankBy\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showPropCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPropAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultAttributeDrillState\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoSortScope\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Items\">\n    <xsd:sequence>\n      <xsd:element name=\"item\" maxOccurs=\"unbounded\" type=\"CT_Item\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Item\">\n    <xsd:attribute name=\"n\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"h\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sd\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"f\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"m\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"d\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"e\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageFields\">\n    <xsd:sequence>\n      <xsd:element name=\"pageField\" maxOccurs=\"unbounded\" type=\"CT_PageField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"item\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"hier\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"cap\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataFields\">\n    <xsd:sequence>\n      <xsd:element name=\"dataField\" maxOccurs=\"unbounded\" type=\"CT_DataField\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataField\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" use=\"optional\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"fld\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"subtotal\" type=\"ST_DataConsolidateFunction\" default=\"sum\"/>\n    <xsd:attribute name=\"showDataAs\" type=\"ST_ShowDataAs\" default=\"normal\"/>\n    <xsd:attribute name=\"baseField\" type=\"xsd:int\" default=\"-1\"/>\n    <xsd:attribute name=\"baseItem\" type=\"xsd:unsignedInt\" default=\"1048832\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_rowItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_colItems\">\n    <xsd:sequence>\n      <xsd:element name=\"i\" maxOccurs=\"unbounded\" type=\"CT_I\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_I\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_X\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_ItemType\" default=\"data\"/>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_X\">\n    <xsd:attribute name=\"v\" type=\"xsd:int\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColFields\">\n    <xsd:sequence>\n      <xsd:element name=\"field\" maxOccurs=\"unbounded\" type=\"CT_Field\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Field\">\n    <xsd:attribute name=\"x\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formats\">\n    <xsd:sequence>\n      <xsd:element name=\"format\" maxOccurs=\"unbounded\" type=\"CT_Format\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Format\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"action\" type=\"ST_FormatAction\" default=\"formatting\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"conditionalFormat\" maxOccurs=\"unbounded\" type=\"CT_ConditionalFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ConditionalFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotAreas\" type=\"CT_PivotAreas\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"scope\" type=\"ST_Scope\" default=\"selection\"/>\n    <xsd:attribute name=\"type\" type=\"ST_Type\" default=\"none\"/>\n    <xsd:attribute name=\"priority\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreas\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Scope\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"selection\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"field\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Type\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"row\"/>\n      <xsd:enumeration value=\"column\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ChartFormats\">\n    <xsd:sequence>\n      <xsd:element name=\"chartFormat\" maxOccurs=\"unbounded\" type=\"CT_ChartFormat\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartFormat\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"chart\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"format\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"series\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchies\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotHierarchy\" maxOccurs=\"unbounded\" type=\"CT_PivotHierarchy\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotHierarchy\">\n    <xsd:sequence>\n      <xsd:element name=\"mps\" minOccurs=\"0\" type=\"CT_MemberProperties\"/>\n      <xsd:element name=\"members\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Members\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"multipleItemSelectionAllowed\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"subtotalTop\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"showInFieldList\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToRow\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToCol\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToPage\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"dragToData\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"dragOff\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"includeNewItemsInFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RowHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"rowHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColHierarchiesUsage\">\n    <xsd:sequence>\n      <xsd:element name=\"colHierarchyUsage\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_HierarchyUsage\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HierarchyUsage\">\n    <xsd:attribute name=\"hierarchyUsage\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"mp\" maxOccurs=\"unbounded\" type=\"CT_MemberProperty\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MemberProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showCell\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showTip\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAsCaption\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nameLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pPos\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"pLen\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"level\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"field\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Members\">\n    <xsd:sequence>\n      <xsd:element name=\"member\" maxOccurs=\"unbounded\" type=\"CT_Member\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"level\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Member\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dimensions\">\n    <xsd:sequence>\n      <xsd:element name=\"dimension\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotDimension\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotDimension\">\n    <xsd:attribute name=\"measure\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"uniqueName\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroups\">\n    <xsd:sequence>\n      <xsd:element name=\"measureGroup\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureGroup\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMaps\">\n    <xsd:sequence>\n      <xsd:element name=\"map\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_MeasureDimensionMap\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureGroup\">\n    <xsd:attribute name=\"name\" use=\"required\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"caption\" use=\"required\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MeasureDimensionMap\">\n    <xsd:attribute name=\"measureGroup\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"dimension\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotTableStyle\">\n    <xsd:attribute name=\"name\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"showRowHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColHeaders\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showColStripes\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilters\">\n    <xsd:sequence>\n      <xsd:element name=\"filter\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_PivotFilter\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotFilter\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_AutoFilter\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fld\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"mpFld\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" use=\"required\" type=\"ST_PivotFilterType\"/>\n    <xsd:attribute name=\"evalOrder\" use=\"optional\" type=\"xsd:int\" default=\"0\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureHier\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"iMeasureFld\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue1\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"stringValue2\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShowDataAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"difference\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"percentDiff\"/>\n      <xsd:enumeration value=\"runTotal\"/>\n      <xsd:enumeration value=\"percentOfRow\"/>\n      <xsd:enumeration value=\"percentOfCol\"/>\n      <xsd:enumeration value=\"percentOfTotal\"/>\n      <xsd:enumeration value=\"index\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ItemType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"countA\"/>\n      <xsd:enumeration value=\"avg\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevP\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varP\"/>\n      <xsd:enumeration value=\"grand\"/>\n      <xsd:enumeration value=\"blank\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormatAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"formatting\"/>\n      <xsd:enumeration value=\"drill\"/>\n      <xsd:enumeration value=\"formula\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FieldSortType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"ascending\"/>\n      <xsd:enumeration value=\"descending\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PivotFilterType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"unknown\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"captionEqual\"/>\n      <xsd:enumeration value=\"captionNotEqual\"/>\n      <xsd:enumeration value=\"captionBeginsWith\"/>\n      <xsd:enumeration value=\"captionNotBeginsWith\"/>\n      <xsd:enumeration value=\"captionEndsWith\"/>\n      <xsd:enumeration value=\"captionNotEndsWith\"/>\n      <xsd:enumeration value=\"captionContains\"/>\n      <xsd:enumeration value=\"captionNotContains\"/>\n      <xsd:enumeration value=\"captionGreaterThan\"/>\n      <xsd:enumeration value=\"captionGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"captionLessThan\"/>\n      <xsd:enumeration value=\"captionLessThanOrEqual\"/>\n      <xsd:enumeration value=\"captionBetween\"/>\n      <xsd:enumeration value=\"captionNotBetween\"/>\n      <xsd:enumeration value=\"valueEqual\"/>\n      <xsd:enumeration value=\"valueNotEqual\"/>\n      <xsd:enumeration value=\"valueGreaterThan\"/>\n      <xsd:enumeration value=\"valueGreaterThanOrEqual\"/>\n      <xsd:enumeration value=\"valueLessThan\"/>\n      <xsd:enumeration value=\"valueLessThanOrEqual\"/>\n      <xsd:enumeration value=\"valueBetween\"/>\n      <xsd:enumeration value=\"valueNotBetween\"/>\n      <xsd:enumeration value=\"dateEqual\"/>\n      <xsd:enumeration value=\"dateNotEqual\"/>\n      <xsd:enumeration value=\"dateOlderThan\"/>\n      <xsd:enumeration value=\"dateOlderThanOrEqual\"/>\n      <xsd:enumeration value=\"dateNewerThan\"/>\n      <xsd:enumeration value=\"dateNewerThanOrEqual\"/>\n      <xsd:enumeration value=\"dateBetween\"/>\n      <xsd:enumeration value=\"dateNotBetween\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextQuarter\"/>\n      <xsd:enumeration value=\"thisQuarter\"/>\n      <xsd:enumeration value=\"lastQuarter\"/>\n      <xsd:enumeration value=\"nextYear\"/>\n      <xsd:enumeration value=\"thisYear\"/>\n      <xsd:enumeration value=\"lastYear\"/>\n      <xsd:enumeration value=\"yearToDate\"/>\n      <xsd:enumeration value=\"Q1\"/>\n      <xsd:enumeration value=\"Q2\"/>\n      <xsd:enumeration value=\"Q3\"/>\n      <xsd:enumeration value=\"Q4\"/>\n      <xsd:enumeration value=\"M1\"/>\n      <xsd:enumeration value=\"M2\"/>\n      <xsd:enumeration value=\"M3\"/>\n      <xsd:enumeration value=\"M4\"/>\n      <xsd:enumeration value=\"M5\"/>\n      <xsd:enumeration value=\"M6\"/>\n      <xsd:enumeration value=\"M7\"/>\n      <xsd:enumeration value=\"M8\"/>\n      <xsd:enumeration value=\"M9\"/>\n      <xsd:enumeration value=\"M10\"/>\n      <xsd:enumeration value=\"M11\"/>\n      <xsd:enumeration value=\"M12\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotArea\">\n    <xsd:sequence>\n      <xsd:element name=\"references\" minOccurs=\"0\" type=\"CT_PivotAreaReferences\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:int\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PivotAreaType\" default=\"normal\"/>\n    <xsd:attribute name=\"dataOnly\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"labelOnly\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandRow\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"grandCol\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"cacheIndex\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"offset\" type=\"ST_Ref\"/>\n    <xsd:attribute name=\"collapsedLevelsAreSubtotals\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldPosition\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PivotAreaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"data\"/>\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"origin\"/>\n      <xsd:enumeration value=\"button\"/>\n      <xsd:enumeration value=\"topEnd\"/>\n      <xsd:enumeration value=\"topRight\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PivotAreaReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"reference\" maxOccurs=\"unbounded\" type=\"CT_PivotAreaReference\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotAreaReference\">\n    <xsd:sequence>\n      <xsd:element name=\"x\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Index\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"field\" use=\"optional\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"selected\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"byPosition\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"relative\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"defaultSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sumSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countASubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"avgSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"maxSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"minSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"productSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"countSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"stdDevPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"varPSubtotal\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Index\">\n    <xsd:attribute name=\"v\" use=\"required\" type=\"xsd:unsignedInt\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Axis\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"axisRow\"/>\n      <xsd:enumeration value=\"axisCol\"/>\n      <xsd:enumeration value=\"axisPage\"/>\n      <xsd:enumeration value=\"axisValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"queryTable\" type=\"CT_QueryTable\"/>\n  <xsd:complexType name=\"CT_QueryTable\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableRefresh\" type=\"CT_QueryTableRefresh\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"headers\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"backgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"firstBackgroundRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refreshOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"growShrinkType\" type=\"ST_GrowShrinkType\" use=\"optional\"\n      default=\"insertDelete\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"removeDataOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"disableEdit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveFormatting\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"adjustColumnWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"intermediate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableRefresh\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableFields\" type=\"CT_QueryTableFields\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"queryTableDeletedFields\" type=\"CT_QueryTableDeletedFields\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SortState\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"preserveSortFilterLayout\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fieldIdWrapped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headersInLastRefresh\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"minimumVersion\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"nextId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"unboundColumnsLeft\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"unboundColumnsRight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableDeletedFields\">\n    <xsd:sequence>\n      <xsd:element name=\"deletedField\" type=\"CT_DeletedField\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DeletedField\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableFields\">\n    <xsd:sequence>\n      <xsd:element name=\"queryTableField\" type=\"CT_QueryTableField\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_QueryTableField\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataBound\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rowNumbers\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"fillFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clipped\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tableColumnId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GrowShrinkType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertDelete\"/>\n      <xsd:enumeration value=\"insertClear\"/>\n      <xsd:enumeration value=\"overwriteClear\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"sst\" type=\"CT_Sst\"/>\n  <xsd:complexType name=\"CT_Sst\">\n    <xsd:sequence>\n      <xsd:element name=\"si\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"uniqueCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PhoneticType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"halfwidthKatakana\"/>\n      <xsd:enumeration value=\"fullwidthKatakana\"/>\n      <xsd:enumeration value=\"Hiragana\"/>\n      <xsd:enumeration value=\"noConversion\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PhoneticAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PhoneticRun\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eb\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RElt\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPrElt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrElt\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rFont\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rst\">\n    <xsd:sequence>\n      <xsd:element name=\"t\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"r\" type=\"CT_RElt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPh\" type=\"CT_PhoneticRun\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"phoneticPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_PhoneticPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PhoneticPr\">\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_PhoneticType\" use=\"optional\" default=\"fullwidthKatakana\"/>\n    <xsd:attribute name=\"alignment\" type=\"ST_PhoneticAlignment\" use=\"optional\" default=\"left\"/>\n  </xsd:complexType>\n  <xsd:element name=\"headers\" type=\"CT_RevisionHeaders\"/>\n  <xsd:element name=\"revisions\" type=\"CT_Revisions\"/>\n  <xsd:complexType name=\"CT_RevisionHeaders\">\n    <xsd:sequence>\n      <xsd:element name=\"header\" type=\"CT_RevisionHeader\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"lastGuid\" type=\"s:ST_Guid\" use=\"optional\"/>\n    <xsd:attribute name=\"shared\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"diskRevisions\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"history\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"trackRevisions\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"exclusive\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"revisionId\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"version\" type=\"xsd:int\" default=\"1\"/>\n    <xsd:attribute name=\"keepChangeHistory\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"protected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preserveHistory\" type=\"xsd:unsignedInt\" default=\"30\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Revisions\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rrc\" type=\"CT_RevisionRowColumn\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rm\" type=\"CT_RevisionMove\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcv\" type=\"CT_RevisionCustomView\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rsnm\" type=\"CT_RevisionSheetRename\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ris\" type=\"CT_RevisionInsertSheet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"raf\" type=\"CT_RevisionAutoFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rdn\" type=\"CT_RevisionDefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcmt\" type=\"CT_RevisionComment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rqt\" type=\"CT_RevisionQueryTableField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcft\" type=\"CT_RevisionConflict\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:attributeGroup name=\"AG_RevData\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ua\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ra\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_RevisionHeader\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetIdMap\" minOccurs=\"1\" maxOccurs=\"1\" type=\"CT_SheetIdMap\"/>\n      <xsd:element name=\"reviewedList\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ReviewedRevisions\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n    <xsd:attribute name=\"maxSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"minRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"maxRId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetIdMap\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetId\" type=\"CT_SheetId\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetId\">\n    <xsd:attribute name=\"val\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReviewedRevisions\">\n    <xsd:sequence>\n      <xsd:element name=\"reviewed\" type=\"CT_Reviewed\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Reviewed\">\n    <xsd:attribute name=\"rId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UndoInfo\">\n    <xsd:attribute name=\"index\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"exp\" type=\"ST_FormulaExpression\" use=\"required\"/>\n    <xsd:attribute name=\"ref3D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"array\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"nf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cs\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dr\" type=\"ST_RefA\" use=\"required\"/>\n    <xsd:attribute name=\"dn\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionRowColumn\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"eol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_rwColActionType\" use=\"required\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionMove\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"undo\" type=\"CT_UndoInfo\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rcc\" type=\"CT_RevisionCellChange\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rfmt\" type=\"CT_RevisionFormatting\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"source\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"destination\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"sourceSheetId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCustomView\">\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionSheetRename\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"oldName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"newName\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionInsertSheet\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetPosition\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionCellChange\">\n    <xsd:sequence>\n      <xsd:element name=\"oc\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"nc\" type=\"CT_Cell\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"odxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ndxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"odxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dxf\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldQuotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"oldPh\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"endOfListFormulaUpdate\" type=\"xsd:boolean\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xfDxf\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionAutoFormatting\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attributeGroup ref=\"AG_AutoFormat\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionComment\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"cell\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"action\" type=\"ST_RevisionAction\" default=\"add\"/>\n    <xsd:attribute name=\"alwaysShow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"author\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"oldLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"newLength\" type=\"xsd:unsignedInt\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionDefinedName\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oldFormula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"customView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldFunction\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldFunctionGroupId\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"shortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"oldShortcutKey\" type=\"xsd:unsignedByte\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"oldHidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldCustomMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldDescription\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldHelp\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldStatusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oldComment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionConflict\">\n    <xsd:attributeGroup ref=\"AG_RevData\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RevisionQueryTableField\">\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"fieldId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_rwColActionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"insertRow\"/>\n      <xsd:enumeration value=\"deleteRow\"/>\n      <xsd:enumeration value=\"insertCol\"/>\n      <xsd:enumeration value=\"deleteCol\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RevisionAction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"add\"/>\n      <xsd:enumeration value=\"delete\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FormulaExpression\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ref\"/>\n      <xsd:enumeration value=\"refError\"/>\n      <xsd:enumeration value=\"area\"/>\n      <xsd:enumeration value=\"areaError\"/>\n      <xsd:enumeration value=\"computedArea\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"users\" type=\"CT_Users\"/>\n  <xsd:complexType name=\"CT_Users\">\n    <xsd:sequence>\n      <xsd:element name=\"userInfo\" minOccurs=\"0\" maxOccurs=\"256\" type=\"CT_SharedUser\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SharedUser\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"dateTime\" type=\"xsd:dateTime\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"worksheet\" type=\"CT_Worksheet\"/>\n  <xsd:element name=\"chartsheet\" type=\"CT_Chartsheet\"/>\n  <xsd:element name=\"dialogsheet\" type=\"CT_Dialogsheet\"/>\n  <xsd:complexType name=\"CT_Macrosheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dialogsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" minOccurs=\"0\" type=\"CT_SheetPr\"/>\n      <xsd:element name=\"sheetViews\" minOccurs=\"0\" type=\"CT_SheetViews\"/>\n      <xsd:element name=\"sheetFormatPr\" minOccurs=\"0\" type=\"CT_SheetFormatPr\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" minOccurs=\"0\" type=\"CT_CustomSheetViews\"/>\n      <xsd:element name=\"printOptions\" minOccurs=\"0\" type=\"CT_PrintOptions\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" minOccurs=\"0\" type=\"CT_PageSetup\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" minOccurs=\"0\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"legacyDrawing\" minOccurs=\"0\" type=\"CT_LegacyDrawing\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Worksheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_SheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dimension\" type=\"CT_SheetDimension\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_SheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetFormatPr\" type=\"CT_SheetFormatPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cols\" type=\"CT_Cols\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sheetData\" type=\"CT_SheetData\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetCalcPr\" type=\"CT_SheetCalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_SheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protectedRanges\" type=\"CT_ProtectedRanges\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scenarios\" type=\"CT_Scenarios\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataConsolidate\" type=\"CT_DataConsolidate\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomSheetViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mergeCells\" type=\"CT_MergeCells\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"phoneticPr\" type=\"CT_PhoneticPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"conditionalFormatting\" type=\"CT_ConditionalFormatting\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"dataValidations\" type=\"CT_DataValidations\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hyperlinks\" type=\"CT_Hyperlinks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customProperties\" type=\"CT_CustomProperties\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellWatches\" type=\"CT_CellWatches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ignoredErrors\" type=\"CT_IgnoredErrors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTags\" type=\"CT_SmartTags\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleObjects\" type=\"CT_OleObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"controls\" type=\"CT_Controls\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableParts\" type=\"CT_TableParts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetCalcPr\">\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetFormatPr\">\n    <xsd:attribute name=\"baseColWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"8\"/>\n    <xsd:attribute name=\"defaultColWidth\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultRowHeight\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zeroHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevelRow\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"outlineLevelCol\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cols\">\n    <xsd:sequence>\n      <xsd:element name=\"col\" type=\"CT_Col\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Col\">\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bestFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customWidth\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"phonetic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellSpan\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellSpans\">\n    <xsd:list itemType=\"ST_CellSpan\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"c\" type=\"CT_Cell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"spans\" type=\"ST_CellSpans\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"customFormat\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ht\" type=\"xsd:double\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"customHeight\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"outlineLevel\" type=\"xsd:unsignedByte\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"collapsed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickTop\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"thickBot\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cell\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_CellFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"is\" type=\"CT_Rst\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"cm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ph\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CellType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"str\"/>\n      <xsd:enumeration value=\"inlineStr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellFormulaType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"array\"/>\n      <xsd:enumeration value=\"dataTable\"/>\n      <xsd:enumeration value=\"shared\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outlinePr\" type=\"CT_OutlinePr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetUpPr\" type=\"CT_PageSetUpPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"syncHorizontal\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncVertical\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"syncRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"transitionEvaluation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"transitionEntry\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filterMode\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"enableFormatConditionsCalculation\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetDimension\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_SheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"pivotSelection\" type=\"CT_PivotSelection\" minOccurs=\"0\" maxOccurs=\"4\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"windowProtection\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowColHeaders\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showZeros\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"rightToLeft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultGridColor\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showWhiteSpace\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" use=\"optional\" default=\"normal\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"64\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"zoomScaleNormal\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScaleSheetLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"zoomScalePageLayoutView\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Pane\">\n    <xsd:attribute name=\"xSplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ySplit\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activePane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"state\" type=\"ST_PaneState\" use=\"optional\" default=\"split\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotSelection\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotArea\" type=\"CT_PivotArea\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"showHeader\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"label\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"extendable\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"axis\" type=\"ST_Axis\" use=\"optional\"/>\n    <xsd:attribute name=\"dimension\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"start\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"activeCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousRow\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"previousCol\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute name=\"click\" type=\"xsd:unsignedInt\" default=\"0\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Selection\">\n    <xsd:attribute name=\"pane\" type=\"ST_Pane\" use=\"optional\" default=\"topLeft\"/>\n    <xsd:attribute name=\"activeCell\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"activeCellId\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\" default=\"A1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"bottomRight\"/>\n      <xsd:enumeration value=\"topRight\"/>\n      <xsd:enumeration value=\"bottomLeft\"/>\n      <xsd:enumeration value=\"topLeft\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBreak\">\n    <xsd:sequence>\n      <xsd:element name=\"brk\" type=\"CT_Break\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"manualBreakCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Break\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"min\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"max\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"man\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pt\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetViewType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"pageBreakPreview\"/>\n      <xsd:enumeration value=\"pageLayout\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OutlinePr\">\n    <xsd:attribute name=\"applyStyles\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"summaryBelow\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"summaryRight\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showOutlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetUpPr\">\n    <xsd:attribute name=\"autoPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataConsolidate\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRefs\" type=\"CT_DataRefs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"function\" type=\"ST_DataConsolidateFunction\" use=\"optional\" default=\"sum\"/>\n    <xsd:attribute name=\"startLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"leftLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"topLabels\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"link\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataConsolidateFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"product\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"stdDevp\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"varp\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DataRefs\">\n    <xsd:sequence>\n      <xsd:element name=\"dataRef\" type=\"CT_DataRef\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataRef\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCells\">\n    <xsd:sequence>\n      <xsd:element name=\"mergeCell\" type=\"CT_MergeCell\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MergeCell\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTags\" type=\"CT_CellSmartTags\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTags\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTag\" type=\"CT_CellSmartTag\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTag\">\n    <xsd:sequence>\n      <xsd:element name=\"cellSmartTagPr\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CellSmartTagPr\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlBased\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellSmartTagPr\">\n    <xsd:attribute name=\"key\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LegacyDrawing\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DrawingHF\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"lho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"che\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"chf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rho\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rhf\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"lff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"cff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfo\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rfe\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rff\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomSheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomSheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pane\" type=\"CT_Pane\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"selection\" type=\"CT_Selection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rowBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colBreaks\" type=\"CT_PageBreak\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"printOptions\" type=\"CT_PrintOptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_PageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"colorId\" type=\"xsd:unsignedInt\" default=\"64\"/>\n    <xsd:attribute name=\"showPageBreaks\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showGridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"outlineSymbols\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"zeroValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"fitToPage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"printArea\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"filter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showAutoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenRows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hiddenColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"filterUnique\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"view\" type=\"ST_SheetViewType\" default=\"normal\"/>\n    <xsd:attribute name=\"showRuler\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"topLeftCell\" type=\"ST_CellRef\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidations\">\n    <xsd:sequence>\n      <xsd:element name=\"dataValidation\" type=\"CT_DataValidation\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"disablePrompts\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataValidation\">\n    <xsd:sequence>\n      <xsd:element name=\"formula1\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"formula2\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_DataValidationType\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"errorStyle\" type=\"ST_DataValidationErrorStyle\" use=\"optional\"\n      default=\"stop\"/>\n    <xsd:attribute name=\"imeMode\" type=\"ST_DataValidationImeMode\" use=\"optional\" default=\"noControl\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_DataValidationOperator\" use=\"optional\" default=\"between\"/>\n    <xsd:attribute name=\"allowBlank\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showDropDown\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInputMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showErrorMessage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errorTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"error\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"promptTitle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"prompt\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DataValidationType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"whole\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"list\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"time\"/>\n      <xsd:enumeration value=\"textLength\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationErrorStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"stop\"/>\n      <xsd:enumeration value=\"warning\"/>\n      <xsd:enumeration value=\"information\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DataValidationImeMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"noControl\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"disabled\"/>\n      <xsd:enumeration value=\"hiragana\"/>\n      <xsd:enumeration value=\"fullKatakana\"/>\n      <xsd:enumeration value=\"halfKatakana\"/>\n      <xsd:enumeration value=\"fullAlpha\"/>\n      <xsd:enumeration value=\"halfAlpha\"/>\n      <xsd:enumeration value=\"fullHangul\"/>\n      <xsd:enumeration value=\"halfHangul\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"expression\"/>\n      <xsd:enumeration value=\"cellIs\"/>\n      <xsd:enumeration value=\"colorScale\"/>\n      <xsd:enumeration value=\"dataBar\"/>\n      <xsd:enumeration value=\"iconSet\"/>\n      <xsd:enumeration value=\"top10\"/>\n      <xsd:enumeration value=\"uniqueValues\"/>\n      <xsd:enumeration value=\"duplicateValues\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContainsText\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n      <xsd:enumeration value=\"containsBlanks\"/>\n      <xsd:enumeration value=\"notContainsBlanks\"/>\n      <xsd:enumeration value=\"containsErrors\"/>\n      <xsd:enumeration value=\"notContainsErrors\"/>\n      <xsd:enumeration value=\"timePeriod\"/>\n      <xsd:enumeration value=\"aboveAverage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TimePeriod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"today\"/>\n      <xsd:enumeration value=\"yesterday\"/>\n      <xsd:enumeration value=\"tomorrow\"/>\n      <xsd:enumeration value=\"last7Days\"/>\n      <xsd:enumeration value=\"thisMonth\"/>\n      <xsd:enumeration value=\"lastMonth\"/>\n      <xsd:enumeration value=\"nextMonth\"/>\n      <xsd:enumeration value=\"thisWeek\"/>\n      <xsd:enumeration value=\"lastWeek\"/>\n      <xsd:enumeration value=\"nextWeek\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConditionalFormattingOperator\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"lessThan\"/>\n      <xsd:enumeration value=\"lessThanOrEqual\"/>\n      <xsd:enumeration value=\"equal\"/>\n      <xsd:enumeration value=\"notEqual\"/>\n      <xsd:enumeration value=\"greaterThanOrEqual\"/>\n      <xsd:enumeration value=\"greaterThan\"/>\n      <xsd:enumeration value=\"between\"/>\n      <xsd:enumeration value=\"notBetween\"/>\n      <xsd:enumeration value=\"containsText\"/>\n      <xsd:enumeration value=\"notContains\"/>\n      <xsd:enumeration value=\"beginsWith\"/>\n      <xsd:enumeration value=\"endsWith\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CfvoType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"percent\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"formula\"/>\n      <xsd:enumeration value=\"percentile\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ConditionalFormatting\">\n    <xsd:sequence>\n      <xsd:element name=\"cfRule\" type=\"CT_CfRule\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CfRule\">\n    <xsd:sequence>\n      <xsd:element name=\"formula\" type=\"ST_Formula\" minOccurs=\"0\" maxOccurs=\"3\"/>\n      <xsd:element name=\"colorScale\" type=\"CT_ColorScale\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dataBar\" type=\"CT_DataBar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"iconSet\" type=\"CT_IconSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfType\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"priority\" type=\"xsd:int\" use=\"required\"/>\n    <xsd:attribute name=\"stopIfTrue\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"aboveAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"operator\" type=\"ST_ConditionalFormattingOperator\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"timePeriod\" type=\"ST_TimePeriod\" use=\"optional\"/>\n    <xsd:attribute name=\"rank\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"stdDev\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"equalAverage\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlinks\">\n    <xsd:sequence>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"location\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"display\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"t\" type=\"ST_CellFormulaType\" use=\"optional\" default=\"normal\"/>\n        <xsd:attribute name=\"aca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"optional\"/>\n        <xsd:attribute name=\"dt2D\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"dtr\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del1\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"del2\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"r1\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"r2\" type=\"ST_CellRef\" use=\"optional\"/>\n        <xsd:attribute name=\"ca\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"bx\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorScale\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBar\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"2\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"minLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"10\"/>\n    <xsd:attribute name=\"maxLength\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"90\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IconSet\">\n    <xsd:sequence>\n      <xsd:element name=\"cfvo\" type=\"CT_Cfvo\" minOccurs=\"2\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"iconSet\" type=\"ST_IconSetType\" use=\"optional\" default=\"3TrafficLights1\"/>\n    <xsd:attribute name=\"showValue\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"percent\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"reverse\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Cfvo\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_CfvoType\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"gte\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMargins\">\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"xsd:double\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PrintOptions\">\n    <xsd:attribute name=\"horizontalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"verticalCentered\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headings\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLines\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"gridLinesSet\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToWidth\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"fitToHeight\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"pageOrder\" type=\"ST_PageOrder\" use=\"optional\" default=\"downThenOver\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellComments\" type=\"ST_CellComments\" use=\"optional\" default=\"none\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"errors\" type=\"ST_PrintError\" use=\"optional\" default=\"displayed\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"downThenOver\"/>\n      <xsd:enumeration value=\"overThenDown\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Orientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellComments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"asDisplayed\"/>\n      <xsd:enumeration value=\"atEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HeaderFooter\">\n    <xsd:sequence>\n      <xsd:element name=\"oddHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oddFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"evenFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstHeader\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"firstFooter\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"differentOddEven\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"differentFirst\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"scaleWithDoc\" type=\"xsd:boolean\" default=\"true\"/>\n    <xsd:attribute name=\"alignWithMargins\" type=\"xsd:boolean\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PrintError\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"displayed\"/>\n      <xsd:enumeration value=\"blank\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"NA\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Scenarios\">\n    <xsd:sequence>\n      <xsd:element name=\"scenario\" type=\"CT_Scenario\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"current\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"show\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"sheet\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"scenarios\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formatCells\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"formatRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"insertHyperlinks\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteColumns\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"deleteRows\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectLockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"sort\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoFilter\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"pivotTables\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"selectUnlockedCells\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRanges\">\n    <xsd:sequence>\n      <xsd:element name=\"protectedRange\" type=\"CT_ProtectedRange\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ProtectedRange\">\n    <xsd:sequence>\n      <xsd:element name=\"securityDescriptor\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"securityDescriptor\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Scenario\">\n    <xsd:sequence>\n      <xsd:element name=\"inputCells\" type=\"CT_InputCells\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"user\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_InputCells\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"deleted\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"undone\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatches\">\n    <xsd:sequence>\n      <xsd:element name=\"cellWatch\" type=\"CT_CellWatch\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellWatch\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Chartsheet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetPr\" type=\"CT_ChartsheetPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetViews\" type=\"CT_ChartsheetViews\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetProtection\" type=\"CT_ChartsheetProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customSheetViews\" type=\"CT_CustomChartsheetViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pageMargins\" minOccurs=\"0\" type=\"CT_PageMargins\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" minOccurs=\"0\" type=\"CT_HeaderFooter\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawing\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"legacyDrawingHF\" type=\"CT_LegacyDrawing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"drawingHF\" type=\"CT_DrawingHF\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"picture\" type=\"CT_SheetBackgroundPicture\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishItems\" type=\"CT_WebPublishItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetPr\">\n    <xsd:sequence>\n      <xsd:element name=\"tabColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetView\" type=\"CT_ChartsheetView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"tabSelected\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"zoomScale\" type=\"xsd:unsignedInt\" default=\"100\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookViewId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ChartsheetProtection\">\n    <xsd:attribute name=\"password\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"content\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"objects\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CsPageSetup\">\n    <xsd:attribute name=\"paperSize\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"paperHeight\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"paperWidth\" type=\"s:ST_PositiveUniversalMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstPageNumber\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"orientation\" type=\"ST_Orientation\" use=\"optional\" default=\"default\"/>\n    <xsd:attribute name=\"usePrinterDefaults\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"blackAndWhite\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"draft\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"useFirstPageNumber\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"horizontalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"verticalDpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"copies\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customSheetView\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomChartsheetView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomChartsheetView\">\n    <xsd:sequence>\n      <xsd:element name=\"pageMargins\" type=\"CT_PageMargins\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pageSetup\" type=\"CT_CsPageSetup\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"headerFooter\" type=\"CT_HeaderFooter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"scale\" type=\"xsd:unsignedInt\" default=\"100\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" default=\"visible\"/>\n    <xsd:attribute name=\"zoomToFit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperties\">\n    <xsd:sequence>\n      <xsd:element name=\"customPr\" type=\"CT_CustomProperty\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomProperty\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"oleObject\" type=\"CT_OleObject\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleObject\">\n    <xsd:sequence>\n      <xsd:element name=\"objectPr\" type=\"CT_ObjectPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"progId\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dvAspect\" type=\"ST_DvAspect\" use=\"optional\" default=\"DVASPECT_CONTENT\"/>\n    <xsd:attribute name=\"link\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"oleUpdate\" type=\"ST_OleUpdate\" use=\"optional\"/>\n    <xsd:attribute name=\"autoLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dde\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DvAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"DVASPECT_CONTENT\"/>\n      <xsd:enumeration value=\"DVASPECT_ICON\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OleUpdate\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"OLEUPDATE_ALWAYS\"/>\n      <xsd:enumeration value=\"OLEUPDATE_ONCALL\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebPublishItems\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishItem\" type=\"CT_WebPublishItem\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishItem\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceType\" type=\"ST_WebSourceType\" use=\"required\"/>\n    <xsd:attribute name=\"sourceRef\" type=\"ST_Ref\" use=\"optional\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Controls\">\n    <xsd:sequence>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:sequence>\n      <xsd:element name=\"controlPr\" type=\"CT_ControlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"shapeId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ControlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"anchor\" type=\"CT_ObjectAnchor\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"defaultSize\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"print\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"disabled\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"recalcAlways\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"uiObject\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoFill\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoLine\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"autoPict\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"macro\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"altText\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"linkedCell\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"listFillRange\" type=\"ST_Formula\" use=\"optional\"/>\n    <xsd:attribute name=\"cf\" type=\"s:ST_Xstring\" use=\"optional\" default=\"pict\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WebSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sheet\"/>\n      <xsd:enumeration value=\"printArea\"/>\n      <xsd:enumeration value=\"autoFilter\"/>\n      <xsd:enumeration value=\"range\"/>\n      <xsd:enumeration value=\"chart\"/>\n      <xsd:enumeration value=\"pivotTable\"/>\n      <xsd:enumeration value=\"query\"/>\n      <xsd:enumeration value=\"label\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_IgnoredErrors\">\n    <xsd:sequence>\n      <xsd:element name=\"ignoredError\" type=\"CT_IgnoredError\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IgnoredError\">\n    <xsd:attribute name=\"sqref\" type=\"ST_Sqref\" use=\"required\"/>\n    <xsd:attribute name=\"evalError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"twoDigitTextYear\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"numberStoredAsText\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"formulaRange\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"unlockedFormula\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"emptyCellReference\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"listDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"calculatedColumn\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PaneState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"split\"/>\n      <xsd:enumeration value=\"frozen\"/>\n      <xsd:enumeration value=\"frozenSplit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableParts\">\n    <xsd:sequence>\n      <xsd:element name=\"tablePart\" type=\"CT_TablePart\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TablePart\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"metadata\" type=\"CT_Metadata\"/>\n  <xsd:complexType name=\"CT_Metadata\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataTypes\" type=\"CT_MetadataTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"metadataStrings\" type=\"CT_MetadataStrings\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mdxMetadata\" type=\"CT_MdxMetadata\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"futureMetadata\" type=\"CT_FutureMetadata\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"cellMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"valueMetadata\" type=\"CT_MetadataBlocks\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"metadataType\" type=\"CT_MetadataType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataType\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"minSupportedVersion\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"ghostRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"ghostCol\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"edit\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"delete\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"copy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormulas\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteValues\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteDataValidation\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteBorders\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteColWidths\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pasteNumberFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"merge\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitFirst\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"splitAll\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"rowColShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearAll\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"clearFormats\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearContents\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"clearComments\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"assign\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"coerce\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"adjust\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"cellMeta\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlocks\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_MetadataBlock\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"rc\" type=\"CT_MetadataRecord\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataRecord\">\n    <xsd:attribute name=\"t\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"bk\" type=\"CT_FutureMetadataBlock\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FutureMetadataBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxMetadata\">\n    <xsd:sequence>\n      <xsd:element name=\"mdx\" type=\"CT_Mdx\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Mdx\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"t\" type=\"CT_MdxTuple\"/>\n      <xsd:element name=\"ms\" type=\"CT_MdxSet\"/>\n      <xsd:element name=\"p\" type=\"CT_MdxMemeberProp\"/>\n      <xsd:element name=\"k\" type=\"CT_MdxKPI\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"f\" type=\"ST_MdxFunctionType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxFunctionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"m\"/>\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"c\"/>\n      <xsd:enumeration value=\"r\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"k\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxTuple\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"ct\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"si\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"fi\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"bc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"fc\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"i\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"u\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"st\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"b\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxSet\">\n    <xsd:sequence>\n      <xsd:element name=\"n\" type=\"CT_MetadataStringIndex\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ns\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"c\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"o\" type=\"ST_MdxSetOrder\" use=\"optional\" default=\"u\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxSetOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"u\"/>\n      <xsd:enumeration value=\"a\"/>\n      <xsd:enumeration value=\"d\"/>\n      <xsd:enumeration value=\"aa\"/>\n      <xsd:enumeration value=\"ad\"/>\n      <xsd:enumeration value=\"na\"/>\n      <xsd:enumeration value=\"nd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MdxMemeberProp\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MdxKPI\">\n    <xsd:attribute name=\"n\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"np\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"p\" type=\"ST_MdxKPIProperty\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MdxKPIProperty\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"v\"/>\n      <xsd:enumeration value=\"g\"/>\n      <xsd:enumeration value=\"s\"/>\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"w\"/>\n      <xsd:enumeration value=\"m\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MetadataStringIndex\">\n    <xsd:attribute name=\"x\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MetadataStrings\">\n    <xsd:sequence>\n      <xsd:element name=\"s\" type=\"CT_XStringElement\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:element name=\"singleXmlCells\" type=\"CT_SingleXmlCells\"/>\n  <xsd:complexType name=\"CT_SingleXmlCells\">\n    <xsd:sequence>\n      <xsd:element name=\"singleXmlCell\" type=\"CT_SingleXmlCell\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SingleXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlCellPr\" type=\"CT_XmlCellPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlCellPr\">\n    <xsd:sequence>\n      <xsd:element name=\"xmlPr\" type=\"CT_XmlPr\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_XmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:element name=\"styleSheet\" type=\"CT_Stylesheet\"/>\n  <xsd:complexType name=\"CT_Stylesheet\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmts\" type=\"CT_NumFmts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fonts\" type=\"CT_Fonts\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fills\" type=\"CT_Fills\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"borders\" type=\"CT_Borders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyleXfs\" type=\"CT_CellStyleXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellXfs\" type=\"CT_CellXfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cellStyles\" type=\"CT_CellStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"dxfs\" type=\"CT_Dxfs\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyles\" type=\"CT_TableStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"colors\" type=\"CT_Colors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellAlignment\">\n    <xsd:attribute name=\"horizontal\" type=\"ST_HorizontalAlignment\" use=\"optional\"/>\n    <xsd:attribute name=\"vertical\" type=\"ST_VerticalAlignment\" default=\"bottom\" use=\"optional\"/>\n    <xsd:attribute name=\"textRotation\" type=\"ST_TextRotation\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapText\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indent\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"relativeIndent\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"justifyLastLine\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"shrinkToFit\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"readingOrder\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextRotation\">\n    <xsd:union>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:maxInclusive value=\"180\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n      <xsd:simpleType>\n        <xsd:restriction base=\"xsd:nonNegativeInteger\">\n          <xsd:enumeration value=\"255\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:union>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"thin\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hair\"/>\n      <xsd:enumeration value=\"mediumDashed\"/>\n      <xsd:enumeration value=\"dashDot\"/>\n      <xsd:enumeration value=\"mediumDashDot\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"mediumDashDotDot\"/>\n      <xsd:enumeration value=\"slantDashDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Borders\">\n    <xsd:sequence>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_BorderPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"top\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"diagonal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertical\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"horizontal\" type=\"CT_BorderPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"diagonalUp\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"diagonalDown\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"outline\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BorderPr\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"style\" type=\"ST_BorderStyle\" use=\"optional\" default=\"none\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellProtection\">\n    <xsd:attribute name=\"locked\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fills\">\n    <xsd:sequence>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"1\">\n      <xsd:element name=\"patternFill\" type=\"CT_PatternFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gradientFill\" type=\"CT_GradientFill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PatternFill\">\n    <xsd:sequence>\n      <xsd:element name=\"fgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bgColor\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"patternType\" type=\"ST_PatternType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"auto\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"indexed\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n    <xsd:attribute name=\"theme\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tint\" type=\"xsd:double\" use=\"optional\" default=\"0.0\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PatternType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"mediumGray\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"darkHorizontal\"/>\n      <xsd:enumeration value=\"darkVertical\"/>\n      <xsd:enumeration value=\"darkDown\"/>\n      <xsd:enumeration value=\"darkUp\"/>\n      <xsd:enumeration value=\"darkGrid\"/>\n      <xsd:enumeration value=\"darkTrellis\"/>\n      <xsd:enumeration value=\"lightHorizontal\"/>\n      <xsd:enumeration value=\"lightVertical\"/>\n      <xsd:enumeration value=\"lightDown\"/>\n      <xsd:enumeration value=\"lightUp\"/>\n      <xsd:enumeration value=\"lightGrid\"/>\n      <xsd:enumeration value=\"lightTrellis\"/>\n      <xsd:enumeration value=\"gray125\"/>\n      <xsd:enumeration value=\"gray0625\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_GradientFill\">\n    <xsd:sequence>\n      <xsd:element name=\"stop\" type=\"CT_GradientStop\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_GradientType\" use=\"optional\" default=\"linear\"/>\n    <xsd:attribute name=\"degree\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"left\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"right\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"top\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"bottom\" type=\"xsd:double\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GradientStop\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"position\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_GradientType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"path\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"general\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"fill\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"centerContinuous\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"justify\"/>\n      <xsd:enumeration value=\"distributed\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumFmts\">\n    <xsd:sequence>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"required\"/>\n    <xsd:attribute name=\"formatCode\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyleXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellXfs\">\n    <xsd:sequence>\n      <xsd:element name=\"xf\" type=\"CT_Xf\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Xf\">\n    <xsd:sequence>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numFmtId\" type=\"ST_NumFmtId\" use=\"optional\"/>\n    <xsd:attribute name=\"fontId\" type=\"ST_FontId\" use=\"optional\"/>\n    <xsd:attribute name=\"fillId\" type=\"ST_FillId\" use=\"optional\"/>\n    <xsd:attribute name=\"borderId\" type=\"ST_BorderId\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"optional\"/>\n    <xsd:attribute name=\"quotePrefix\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"pivotButton\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"applyNumberFormat\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFont\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyFill\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyBorder\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyAlignment\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"applyProtection\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"cellStyle\" type=\"CT_CellStyle\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"xfId\" type=\"ST_CellStyleXfId\" use=\"required\"/>\n    <xsd:attribute name=\"builtinId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"iLevel\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"customBuiltin\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxfs\">\n    <xsd:sequence>\n      <xsd:element name=\"dxf\" type=\"CT_Dxf\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Dxf\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fill\" type=\"CT_Fill\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"alignment\" type=\"CT_CellAlignment\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"border\" type=\"CT_Border\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"protection\" type=\"CT_CellProtection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumFmtId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FontId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CellStyleXfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DxfId\">\n    <xsd:restriction base=\"xsd:unsignedInt\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Colors\">\n    <xsd:sequence>\n      <xsd:element name=\"indexedColors\" type=\"CT_IndexedColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"mruColors\" type=\"CT_MRUColors\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IndexedColors\">\n    <xsd:sequence>\n      <xsd:element name=\"rgbColor\" type=\"CT_RgbColor\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MRUColors\">\n    <xsd:sequence>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RgbColor\">\n    <xsd:attribute name=\"rgb\" type=\"ST_UnsignedIntHex\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyle\" type=\"CT_TableStyle\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultTableStyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"defaultPivotStyle\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyle\">\n    <xsd:sequence>\n      <xsd:element name=\"tableStyleElement\" type=\"CT_TableStyleElement\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"pivot\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"table\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableStyleElement\">\n    <xsd:attribute name=\"type\" type=\"ST_TableStyleType\" use=\"required\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"dxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableStyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"headerRow\"/>\n      <xsd:enumeration value=\"totalRow\"/>\n      <xsd:enumeration value=\"firstColumn\"/>\n      <xsd:enumeration value=\"lastColumn\"/>\n      <xsd:enumeration value=\"firstRowStripe\"/>\n      <xsd:enumeration value=\"secondRowStripe\"/>\n      <xsd:enumeration value=\"firstColumnStripe\"/>\n      <xsd:enumeration value=\"secondColumnStripe\"/>\n      <xsd:enumeration value=\"firstHeaderCell\"/>\n      <xsd:enumeration value=\"lastHeaderCell\"/>\n      <xsd:enumeration value=\"firstTotalCell\"/>\n      <xsd:enumeration value=\"lastTotalCell\"/>\n      <xsd:enumeration value=\"firstSubtotalColumn\"/>\n      <xsd:enumeration value=\"secondSubtotalColumn\"/>\n      <xsd:enumeration value=\"thirdSubtotalColumn\"/>\n      <xsd:enumeration value=\"firstSubtotalRow\"/>\n      <xsd:enumeration value=\"secondSubtotalRow\"/>\n      <xsd:enumeration value=\"thirdSubtotalRow\"/>\n      <xsd:enumeration value=\"blankRow\"/>\n      <xsd:enumeration value=\"firstColumnSubheading\"/>\n      <xsd:enumeration value=\"secondColumnSubheading\"/>\n      <xsd:enumeration value=\"thirdColumnSubheading\"/>\n      <xsd:enumeration value=\"firstRowSubheading\"/>\n      <xsd:enumeration value=\"secondRowSubheading\"/>\n      <xsd:enumeration value=\"thirdRowSubheading\"/>\n      <xsd:enumeration value=\"pageFieldLabels\"/>\n      <xsd:enumeration value=\"pageFieldValues\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_BooleanProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSize\">\n    <xsd:attribute name=\"val\" type=\"xsd:double\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IntProperty\">\n    <xsd:attribute name=\"val\" type=\"xsd:int\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignFontProperty\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontScheme\">\n    <xsd:attribute name=\"val\" type=\"ST_FontScheme\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontScheme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"major\"/>\n      <xsd:enumeration value=\"minor\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_UnderlineProperty\">\n    <xsd:attribute name=\"val\" type=\"ST_UnderlineValues\" use=\"optional\" default=\"single\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UnderlineValues\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"singleAccounting\"/>\n      <xsd:enumeration value=\"doubleAccounting\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FontName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_IntProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"b\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"i\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"strike\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"outline\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shadow\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"condense\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extend\" type=\"CT_BooleanProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sz\" type=\"CT_FontSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"u\" type=\"CT_UnderlineProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignFontProperty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"scheme\" type=\"CT_FontScheme\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"14\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_AutoFormat\">\n    <xsd:attribute name=\"autoFormatId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"applyNumberFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyBorderFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyFontFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyPatternFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyAlignmentFormats\" type=\"xsd:boolean\"/>\n    <xsd:attribute name=\"applyWidthHeightFormats\" type=\"xsd:boolean\"/>\n  </xsd:attributeGroup>\n  <xsd:element name=\"externalLink\" type=\"CT_ExternalLink\"/>\n  <xsd:complexType name=\"CT_ExternalLink\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"externalBook\" type=\"CT_ExternalBook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"ddeLink\" type=\"CT_DdeLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        <xsd:element name=\"oleLink\" type=\"CT_OleLink\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      </xsd:choice>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalBook\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetNames\" type=\"CT_ExternalSheetNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_ExternalDefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheetDataSet\" type=\"CT_ExternalSheetDataSet\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetNames\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetName\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_ExternalSheetName\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_ExternalDefinedName\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalDefinedName\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"refersTo\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetDataSet\">\n    <xsd:sequence>\n      <xsd:element name=\"sheetData\" type=\"CT_ExternalSheetData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalSheetData\">\n    <xsd:sequence>\n      <xsd:element name=\"row\" type=\"CT_ExternalRow\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"refreshError\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalRow\">\n    <xsd:sequence>\n      <xsd:element name=\"cell\" type=\"CT_ExternalCell\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalCell\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"optional\"/>\n    <xsd:attribute name=\"t\" type=\"ST_CellType\" use=\"optional\" default=\"n\"/>\n    <xsd:attribute name=\"vm\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeLink\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItems\" type=\"CT_DdeItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ddeService\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"ddeTopic\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItems\">\n    <xsd:sequence>\n      <xsd:element name=\"ddeItem\" type=\"CT_DdeItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeItem\">\n    <xsd:sequence>\n      <xsd:element name=\"values\" type=\"CT_DdeValues\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" default=\"0\"/>\n    <xsd:attribute name=\"ole\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValues\">\n    <xsd:sequence>\n      <xsd:element name=\"value\" minOccurs=\"1\" maxOccurs=\"unbounded\" type=\"CT_DdeValue\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rows\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"cols\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DdeValue\">\n    <xsd:sequence>\n      <xsd:element name=\"val\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_DdeValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DdeValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"str\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_OleLink\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItems\" type=\"CT_OleItems\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItems\">\n    <xsd:sequence>\n      <xsd:element name=\"oleItem\" type=\"CT_OleItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleItem\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"icon\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"advise\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"preferPic\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:element name=\"table\" type=\"CT_Table\"/>\n  <xsd:complexType name=\"CT_Table\">\n    <xsd:sequence>\n      <xsd:element name=\"autoFilter\" type=\"CT_AutoFilter\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sortState\" type=\"CT_SortState\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableColumns\" type=\"CT_TableColumns\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tableStyleInfo\" type=\"CT_TableStyleInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"displayName\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n    <xsd:attribute name=\"tableType\" type=\"ST_TableType\" use=\"optional\" default=\"worksheet\"/>\n    <xsd:attribute name=\"headerRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"insertRow\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"insertRowShift\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"totalsRowCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"totalsRowShown\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"published\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"tableBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowBorderDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"connectionId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TableType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"worksheet\"/>\n      <xsd:enumeration value=\"xml\"/>\n      <xsd:enumeration value=\"queryTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TableStyleInfo\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"showFirstColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showLastColumn\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showRowStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n    <xsd:attribute name=\"showColumnStripes\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumns\">\n    <xsd:sequence>\n      <xsd:element name=\"tableColumn\" type=\"CT_TableColumn\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableColumn\">\n    <xsd:sequence>\n      <xsd:element name=\"calculatedColumnFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"totalsRowFormula\" type=\"CT_TableFormula\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"xmlColumnPr\" type=\"CT_XmlColumnPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"uniqueName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"totalsRowFunction\" type=\"ST_TotalsRowFunction\" use=\"optional\"\n      default=\"none\"/>\n    <xsd:attribute name=\"totalsRowLabel\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"queryTableFieldId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"dataDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowDxfId\" type=\"ST_DxfId\" use=\"optional\"/>\n    <xsd:attribute name=\"headerRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"dataCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"totalsRowCellStyle\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TableFormula\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"array\" type=\"xsd:boolean\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TotalsRowFunction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"sum\"/>\n      <xsd:enumeration value=\"min\"/>\n      <xsd:enumeration value=\"max\"/>\n      <xsd:enumeration value=\"average\"/>\n      <xsd:enumeration value=\"count\"/>\n      <xsd:enumeration value=\"countNums\"/>\n      <xsd:enumeration value=\"stdDev\"/>\n      <xsd:enumeration value=\"var\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_XmlColumnPr\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"mapId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"denormalized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"xmlDataType\" type=\"ST_XmlDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_XmlDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:element name=\"volTypes\" type=\"CT_VolTypes\"/>\n  <xsd:complexType name=\"CT_VolTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"volType\" type=\"CT_VolType\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolType\">\n    <xsd:sequence>\n      <xsd:element name=\"main\" type=\"CT_VolMain\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_VolDepType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolMain\">\n    <xsd:sequence>\n      <xsd:element name=\"tp\" type=\"CT_VolTopic\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"first\" type=\"s:ST_Xstring\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopic\">\n    <xsd:sequence>\n      <xsd:element name=\"v\" type=\"s:ST_Xstring\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"stp\" type=\"s:ST_Xstring\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tr\" type=\"CT_VolTopicRef\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"t\" type=\"ST_VolValueType\" use=\"optional\" default=\"n\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VolTopicRef\">\n    <xsd:attribute name=\"r\" type=\"ST_CellRef\" use=\"required\"/>\n    <xsd:attribute name=\"s\" type=\"xsd:unsignedInt\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VolDepType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"realTimeData\"/>\n      <xsd:enumeration value=\"olapFunctions\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VolValueType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"b\"/>\n      <xsd:enumeration value=\"n\"/>\n      <xsd:enumeration value=\"e\"/>\n      <xsd:enumeration value=\"s\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:element name=\"workbook\" type=\"CT_Workbook\"/>\n  <xsd:complexType name=\"CT_Workbook\">\n    <xsd:sequence>\n      <xsd:element name=\"fileVersion\" type=\"CT_FileVersion\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileSharing\" type=\"CT_FileSharing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookPr\" type=\"CT_WorkbookPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"workbookProtection\" type=\"CT_WorkbookProtection\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"bookViews\" type=\"CT_BookViews\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sheets\" type=\"CT_Sheets\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"functionGroups\" type=\"CT_FunctionGroups\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"externalReferences\" type=\"CT_ExternalReferences\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"definedNames\" type=\"CT_DefinedNames\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"calcPr\" type=\"CT_CalcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"oleSize\" type=\"CT_OleSize\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"customWorkbookViews\" type=\"CT_CustomWorkbookViews\" minOccurs=\"0\"\n        maxOccurs=\"1\"/>\n      <xsd:element name=\"pivotCaches\" type=\"CT_PivotCaches\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"smartTagTypes\" type=\"CT_SmartTagTypes\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"webPublishing\" type=\"CT_WebPublishing\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"fileRecoveryPr\" type=\"CT_FileRecoveryPr\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"webPublishObjects\" type=\"CT_WebPublishObjects\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileVersion\">\n    <xsd:attribute name=\"appName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lastEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lowestEdited\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rupBuild\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"codeName\" type=\"s:ST_Guid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"workbookView\" type=\"CT_BookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" type=\"CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"visibility\" type=\"ST_Visibility\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"firstSheet\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"activeTab\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"autoFilterDateGrouping\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Visibility\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CustomWorkbookViews\">\n    <xsd:sequence>\n      <xsd:element name=\"customWorkbookView\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n        type=\"CT_CustomWorkbookView\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomWorkbookView\">\n    <xsd:sequence>\n      <xsd:element name=\"extLst\" minOccurs=\"0\" type=\"CT_ExtensionList\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"guid\" type=\"s:ST_Guid\" use=\"required\"/>\n    <xsd:attribute name=\"autoUpdate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"mergeInterval\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"changesSavedWin\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"onlySync\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"personalView\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"includePrintSettings\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"includeHiddenRowCol\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"maximized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"minimized\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showHorizontalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showVerticalScroll\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showSheetTabs\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"xWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"yWindow\" type=\"xsd:int\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"windowWidth\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"windowHeight\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"tabRatio\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"600\"/>\n    <xsd:attribute name=\"activeSheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"showFormulaBar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showStatusbar\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"showComments\" type=\"ST_Comments\" use=\"optional\" default=\"commIndicator\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Comments\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"commNone\"/>\n      <xsd:enumeration value=\"commIndicator\"/>\n      <xsd:enumeration value=\"commIndAndComment\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Objects\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"placeholders\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Sheets\">\n    <xsd:sequence>\n      <xsd:element name=\"sheet\" type=\"CT_Sheet\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sheet\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sheetId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"state\" type=\"ST_SheetState\" use=\"optional\" default=\"visible\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SheetState\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"visible\"/>\n      <xsd:enumeration value=\"hidden\"/>\n      <xsd:enumeration value=\"veryHidden\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WorkbookPr\">\n    <xsd:attribute name=\"date1904\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showObjects\" type=\"ST_Objects\" use=\"optional\" default=\"all\"/>\n    <xsd:attribute name=\"showBorderUnselectedTables\" type=\"xsd:boolean\" use=\"optional\"\n      default=\"true\"/>\n    <xsd:attribute name=\"filterPrivacy\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"promptedSolutions\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showInkAnnotation\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"backupFile\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"saveExternalLinkValues\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"updateLinks\" type=\"ST_UpdateLinks\" use=\"optional\" default=\"userSet\"/>\n    <xsd:attribute name=\"codeName\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"hidePivotFieldList\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"showPivotChartFilter\" type=\"xsd:boolean\" default=\"false\"/>\n    <xsd:attribute name=\"allowRefreshQuery\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"publishItems\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"checkCompatibility\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"autoCompressPictures\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"refreshAllConnections\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"defaultThemeVersion\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_UpdateLinks\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"userSet\"/>\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"always\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:attribute name=\"embed\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"show\" type=\"ST_SmartTagShow\" use=\"optional\" default=\"all\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SmartTagShow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"all\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"noIndicator\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SmartTagTypes\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceUri\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_Xstring\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileRecoveryPr\">\n    <xsd:attribute name=\"autoRecover\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"crashSave\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"dataExtractLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"repairLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalcPr\">\n    <xsd:attribute name=\"calcId\" type=\"xsd:unsignedInt\"/>\n    <xsd:attribute name=\"calcMode\" type=\"ST_CalcMode\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"fullCalcOnLoad\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"refMode\" type=\"ST_RefMode\" use=\"optional\" default=\"A1\"/>\n    <xsd:attribute name=\"iterate\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"iterateCount\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"100\"/>\n    <xsd:attribute name=\"iterateDelta\" type=\"xsd:double\" use=\"optional\" default=\"0.001\"/>\n    <xsd:attribute name=\"fullPrecision\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcCompleted\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"calcOnSave\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentCalc\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"concurrentManualCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"forceFullCalc\" type=\"xsd:boolean\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CalcMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"manual\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"autoNoTable\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_RefMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"A1\"/>\n      <xsd:enumeration value=\"R1C1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DefinedNames\">\n    <xsd:sequence>\n      <xsd:element name=\"definedName\" type=\"CT_DefinedName\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DefinedName\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"ST_Formula\">\n        <xsd:attribute name=\"name\" type=\"s:ST_Xstring\" use=\"required\"/>\n        <xsd:attribute name=\"comment\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"customMenu\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"description\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"help\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"statusBar\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"localSheetId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"hidden\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"function\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"vbProcedure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"xlm\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"functionGroupId\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n        <xsd:attribute name=\"shortcutKey\" type=\"s:ST_Xstring\" use=\"optional\"/>\n        <xsd:attribute name=\"publishToServer\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n        <xsd:attribute name=\"workbookParameter\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReferences\">\n    <xsd:sequence>\n      <xsd:element name=\"externalReference\" type=\"CT_ExternalReference\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ExternalReference\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SheetBackgroundPicture\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCaches\">\n    <xsd:sequence>\n      <xsd:element name=\"pivotCache\" type=\"CT_PivotCache\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PivotCache\">\n    <xsd:attribute name=\"cacheId\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FileSharing\">\n    <xsd:attribute name=\"readOnlyRecommended\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"userName\" type=\"s:ST_Xstring\"/>\n    <xsd:attribute name=\"reservationPassword\" type=\"ST_UnsignedShortHex\"/>\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OleSize\">\n    <xsd:attribute name=\"ref\" type=\"ST_Ref\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WorkbookProtection\">\n    <xsd:attribute name=\"workbookPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPassword\" type=\"ST_UnsignedShortHex\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsPasswordCharacterSet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lockStructure\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockWindows\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"lockRevision\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"revisionsAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"revisionsSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookAlgorithmName\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookHashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSaltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"workbookSpinCount\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishing\">\n    <xsd:attribute name=\"css\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"thicket\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"longFileNames\" type=\"xsd:boolean\" use=\"optional\" default=\"true\"/>\n    <xsd:attribute name=\"vml\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"allowPng\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"targetScreenSize\" type=\"ST_TargetScreenSize\" use=\"optional\"\n      default=\"800x600\"/>\n    <xsd:attribute name=\"dpi\" type=\"xsd:unsignedInt\" use=\"optional\" default=\"96\"/>\n    <xsd:attribute name=\"codePage\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FunctionGroups\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"functionGroup\" type=\"CT_FunctionGroup\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"builtInGroupCount\" type=\"xsd:unsignedInt\" default=\"16\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FunctionGroup\">\n    <xsd:attribute name=\"name\" type=\"s:ST_Xstring\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObjects\">\n    <xsd:sequence>\n      <xsd:element name=\"webPublishObject\" type=\"CT_WebPublishObject\" minOccurs=\"1\"\n        maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"count\" type=\"xsd:unsignedInt\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WebPublishObject\">\n    <xsd:attribute name=\"id\" type=\"xsd:unsignedInt\" use=\"required\"/>\n    <xsd:attribute name=\"divId\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"sourceObject\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"destinationFile\" type=\"s:ST_Xstring\" use=\"required\"/>\n    <xsd:attribute name=\"title\" type=\"s:ST_Xstring\" use=\"optional\"/>\n    <xsd:attribute name=\"autoRepublish\" type=\"xsd:boolean\" use=\"optional\" default=\"false\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:schemas-microsoft-com:vml\"\n  xmlns:pvml=\"urn:schemas-microsoft-com:office:powerpoint\"\n  xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n  xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:w10=\"urn:schemas-microsoft-com:office:word\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:vml\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:office\"\n    schemaLocation=\"vml-officeDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n    schemaLocation=\"wml.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:word\"\n    schemaLocation=\"vml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:excel\"\n    schemaLocation=\"vml-spreadsheetDrawing.xsd\"/>\n  <xsd:import namespace=\"urn:schemas-microsoft-com:office:powerpoint\"\n    schemaLocation=\"vml-presentationDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attributeGroup name=\"AG_Id\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Style\">\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Type\">\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Adj\">\n    <xsd:attribute name=\"adj\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Path\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Fill\">\n    <xsd:attribute name=\"filled\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Chromakey\">\n    <xsd:attribute name=\"chromakey\" type=\"s:ST_ColorType\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_Ext\">\n    <xsd:attribute name=\"ext\" form=\"qualified\" type=\"ST_Ext\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_CoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"href\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"target\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"class\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"title\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"alt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordsize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"coordorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"print\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"stroked\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeweight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeCoreAttributes\">\n    <xsd:attribute ref=\"o:spid\"/>\n    <xsd:attribute ref=\"o:oned\"/>\n    <xsd:attribute ref=\"o:regroupid\"/>\n    <xsd:attribute ref=\"o:doubleclicknotify\"/>\n    <xsd:attribute ref=\"o:button\"/>\n    <xsd:attribute ref=\"o:userhidden\"/>\n    <xsd:attribute ref=\"o:bullet\"/>\n    <xsd:attribute ref=\"o:hr\"/>\n    <xsd:attribute ref=\"o:hrstd\"/>\n    <xsd:attribute ref=\"o:hrnoshade\"/>\n    <xsd:attribute ref=\"o:hrpct\"/>\n    <xsd:attribute ref=\"o:hralign\"/>\n    <xsd:attribute ref=\"o:allowincell\"/>\n    <xsd:attribute ref=\"o:allowoverlap\"/>\n    <xsd:attribute ref=\"o:userdrawn\"/>\n    <xsd:attribute ref=\"o:bordertopcolor\"/>\n    <xsd:attribute ref=\"o:borderleftcolor\"/>\n    <xsd:attribute ref=\"o:borderbottomcolor\"/>\n    <xsd:attribute ref=\"o:borderrightcolor\"/>\n    <xsd:attribute ref=\"o:dgmlayout\"/>\n    <xsd:attribute ref=\"o:dgmnodekind\"/>\n    <xsd:attribute ref=\"o:dgmlayoutmru\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_OfficeShapeAttributes\">\n    <xsd:attribute ref=\"o:spt\"/>\n    <xsd:attribute ref=\"o:connectortype\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"o:oleicon\"/>\n    <xsd:attribute ref=\"o:ole\"/>\n    <xsd:attribute ref=\"o:preferrelative\"/>\n    <xsd:attribute ref=\"o:cliptowrap\"/>\n    <xsd:attribute ref=\"o:clip\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllCoreAttributes\">\n    <xsd:attributeGroup ref=\"AG_CoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeCoreAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_AllShapeAttributes\">\n    <xsd:attributeGroup ref=\"AG_ShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_OfficeShapeAttributes\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_ImageAttributes\">\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropleft\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"croptop\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropright\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"cropbottom\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gain\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"blacklevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gamma\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"grayscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"bilevel\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_StrokeAttributes\">\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:forcedash\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n  </xsd:attributeGroup>\n  <xsd:group name=\"EG_ShapeElements\">\n    <xsd:choice>\n      <xsd:element ref=\"path\"/>\n      <xsd:element ref=\"formulas\"/>\n      <xsd:element ref=\"handles\"/>\n      <xsd:element ref=\"fill\"/>\n      <xsd:element ref=\"stroke\"/>\n      <xsd:element ref=\"shadow\"/>\n      <xsd:element ref=\"textbox\"/>\n      <xsd:element ref=\"textpath\"/>\n      <xsd:element ref=\"imagedata\"/>\n      <xsd:element ref=\"o:skew\"/>\n      <xsd:element ref=\"o:extrusion\"/>\n      <xsd:element ref=\"o:callout\"/>\n      <xsd:element ref=\"o:lock\"/>\n      <xsd:element ref=\"o:clippath\"/>\n      <xsd:element ref=\"o:signatureline\"/>\n      <xsd:element ref=\"w10:wrap\"/>\n      <xsd:element ref=\"w10:anchorlock\"/>\n      <xsd:element ref=\"w10:bordertop\"/>\n      <xsd:element ref=\"w10:borderbottom\"/>\n      <xsd:element ref=\"w10:borderleft\"/>\n      <xsd:element ref=\"w10:borderright\"/>\n      <xsd:element ref=\"x:ClientData\" minOccurs=\"0\"/>\n      <xsd:element ref=\"pvml:textdata\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:element name=\"shape\" type=\"CT_Shape\"/>\n  <xsd:element name=\"shapetype\" type=\"CT_Shapetype\"/>\n  <xsd:element name=\"group\" type=\"CT_Group\"/>\n  <xsd:element name=\"background\" type=\"CT_Background\"/>\n  <xsd:complexType name=\"CT_Shape\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n      <xsd:element ref=\"pvml:iscomment\"/>\n      <xsd:element ref=\"o:equationxml\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Type\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:gfxdata\"/>\n    <xsd:attribute name=\"equationxml\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shapetype\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"o:complex\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Adj\"/>\n    <xsd:attributeGroup ref=\"AG_Path\"/>\n    <xsd:attribute ref=\"o:master\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Group\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"group\"/>\n      <xsd:element ref=\"shape\"/>\n      <xsd:element ref=\"shapetype\"/>\n      <xsd:element ref=\"arc\"/>\n      <xsd:element ref=\"curve\"/>\n      <xsd:element ref=\"image\"/>\n      <xsd:element ref=\"line\"/>\n      <xsd:element ref=\"oval\"/>\n      <xsd:element ref=\"polyline\"/>\n      <xsd:element ref=\"rect\"/>\n      <xsd:element ref=\"roundrect\"/>\n      <xsd:element ref=\"o:diagram\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute name=\"editas\" type=\"ST_EditAs\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:tableproperties\"/>\n    <xsd:attribute ref=\"o:tablelimits\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:element ref=\"fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Fill\"/>\n    <xsd:attribute ref=\"o:bwmode\"/>\n    <xsd:attribute ref=\"o:bwpure\"/>\n    <xsd:attribute ref=\"o:bwnormal\"/>\n    <xsd:attribute ref=\"o:targetscreensize\"/>\n  </xsd:complexType>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:element name=\"formulas\" type=\"CT_Formulas\"/>\n  <xsd:element name=\"handles\" type=\"CT_Handles\"/>\n  <xsd:element name=\"imagedata\" type=\"CT_ImageData\"/>\n  <xsd:element name=\"path\" type=\"CT_Path\"/>\n  <xsd:element name=\"textbox\" type=\"CT_Textbox\"/>\n  <xsd:element name=\"shadow\" type=\"CT_Shadow\"/>\n  <xsd:element name=\"stroke\" type=\"CT_Stroke\"/>\n  <xsd:element name=\"textpath\" type=\"CT_TextPath\"/>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:fill\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute name=\"size\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"position\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"aspect\" type=\"ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"alignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"focus\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focussize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"focusposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"method\" type=\"ST_FillMethod\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:opacity2\"/>\n    <xsd:attribute name=\"recolor\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotate\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:relid\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Formulas\">\n    <xsd:sequence>\n      <xsd:element name=\"f\" type=\"CT_F\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_F\">\n    <xsd:attribute name=\"eqn\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Handles\">\n    <xsd:sequence>\n      <xsd:element name=\"h\" type=\"CT_H\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_H\">\n    <xsd:attribute name=\"position\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"polar\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"map\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"invx\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"invy\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"switch\" type=\"s:ST_TrueFalseBlank\"/>\n    <xsd:attribute name=\"xrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"yrange\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"radiusrange\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ImageData\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_Chromakey\"/>\n    <xsd:attribute name=\"embosscolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"recolortarget\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute ref=\"o:href\"/>\n    <xsd:attribute ref=\"o:althref\"/>\n    <xsd:attribute ref=\"o:title\"/>\n    <xsd:attribute ref=\"o:oleid\"/>\n    <xsd:attribute ref=\"o:detectmouseclick\"/>\n    <xsd:attribute ref=\"o:movie\"/>\n    <xsd:attribute ref=\"o:relid\"/>\n    <xsd:attribute ref=\"r:id\"/>\n    <xsd:attribute ref=\"r:pict\"/>\n    <xsd:attribute ref=\"r:href\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Path\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"limo\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"textboxrect\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fillok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shadowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"arrowok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"gradientshapeok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textpathok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpenok\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:connecttype\"/>\n    <xsd:attribute ref=\"o:connectlocs\"/>\n    <xsd:attribute ref=\"o:connectangles\"/>\n    <xsd:attribute ref=\"o:extrusionok\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Shadow\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ShadowType\" use=\"optional\"/>\n    <xsd:attribute name=\"obscured\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"offset2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Stroke\">\n    <xsd:sequence>\n      <xsd:element ref=\"o:left\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:top\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:right\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:bottom\" minOccurs=\"0\"/>\n      <xsd:element ref=\"o:column\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_StrokeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Textbox\">\n    <xsd:choice>\n      <xsd:element ref=\"w:txbxContent\" minOccurs=\"0\"/>\n      <xsd:any namespace=\"##local\" processContents=\"skip\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"inset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"o:singleclick\"/>\n    <xsd:attribute ref=\"o:insetmode\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TextPath\">\n    <xsd:attributeGroup ref=\"AG_Id\"/>\n    <xsd:attributeGroup ref=\"AG_Style\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fitpath\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"trim\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"xscale\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"string\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"arc\" type=\"CT_Arc\"/>\n  <xsd:element name=\"curve\" type=\"CT_Curve\"/>\n  <xsd:element name=\"image\" type=\"CT_Image\"/>\n  <xsd:element name=\"line\" type=\"CT_Line\"/>\n  <xsd:element name=\"oval\" type=\"CT_Oval\"/>\n  <xsd:element name=\"polyline\" type=\"CT_PolyLine\"/>\n  <xsd:element name=\"rect\" type=\"CT_Rect\"/>\n  <xsd:element name=\"roundrect\" type=\"CT_RoundRect\"/>\n  <xsd:complexType name=\"CT_Arc\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"startAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"endAngle\" type=\"xsd:decimal\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Curve\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control1\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"control2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Image\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_ImageAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Line\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"from\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"to\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Oval\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PolyLine\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\"/>\n      <xsd:element ref=\"o:ink\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"points\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RoundRect\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:group ref=\"EG_ShapeElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attributeGroup ref=\"AG_AllCoreAttributes\"/>\n    <xsd:attributeGroup ref=\"AG_AllShapeAttributes\"/>\n    <xsd:attribute name=\"arcsize\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Ext\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"view\"/>\n      <xsd:enumeration value=\"edit\"/>\n      <xsd:enumeration value=\"backwardCompatible\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"frame\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillMethod\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"linear\"/>\n      <xsd:enumeration value=\"sigma\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"linear sigma\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ShadowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"emboss\"/>\n      <xsd:enumeration value=\"perspective\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeLineStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thinThin\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeJoinStyle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"bevel\"/>\n      <xsd:enumeration value=\"miter\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeEndCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"flat\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"round\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowLength\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"short\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"long\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"narrow\"/>\n      <xsd:enumeration value=\"medium\"/>\n      <xsd:enumeration value=\"wide\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_StrokeArrowType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"block\"/>\n      <xsd:enumeration value=\"classic\"/>\n      <xsd:enumeration value=\"oval\"/>\n      <xsd:enumeration value=\"diamond\"/>\n      <xsd:enumeration value=\"open\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ImageAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ignore\"/>\n      <xsd:enumeration value=\"atMost\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_EditAs\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"canvas\"/>\n      <xsd:enumeration value=\"orgchart\"/>\n      <xsd:enumeration value=\"radial\"/>\n      <xsd:enumeration value=\"cycle\"/>\n      <xsd:enumeration value=\"stacked\"/>\n      <xsd:enumeration value=\"venn\"/>\n      <xsd:enumeration value=\"bullseye\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:office\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"urn:schemas-microsoft-com:vml\" schemaLocation=\"vml-main.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:attribute name=\"bwmode\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwpure\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"bwnormal\" type=\"ST_BWMode\"/>\n  <xsd:attribute name=\"targetscreensize\" type=\"ST_ScreenSize\"/>\n  <xsd:attribute name=\"insetmode\" type=\"ST_InsetMode\" default=\"custom\"/>\n  <xsd:attribute name=\"spt\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"wrapcoords\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"oned\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"regroupid\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"doubleclicknotify\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"connectortype\" type=\"ST_ConnectorType\" default=\"straight\"/>\n  <xsd:attribute name=\"button\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userhidden\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"forcedash\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleicon\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"ole\" type=\"s:ST_TrueFalseBlank\"/>\n  <xsd:attribute name=\"preferrelative\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"cliptowrap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"clip\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bullet\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hr\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrstd\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrnoshade\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"hrpct\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"hralign\" type=\"ST_HrAlign\" default=\"left\"/>\n  <xsd:attribute name=\"allowincell\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"allowoverlap\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"userdrawn\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"bordertopcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderleftcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderbottomcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"borderrightcolor\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connecttype\" type=\"ST_ConnectType\"/>\n  <xsd:attribute name=\"connectlocs\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"connectangles\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"master\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"extrusionok\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"href\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"althref\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"title\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"singleclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"oleid\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"detectmouseclick\" type=\"s:ST_TrueFalse\"/>\n  <xsd:attribute name=\"movie\" type=\"xsd:float\"/>\n  <xsd:attribute name=\"spid\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"opacity2\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"relid\" type=\"r:ST_RelationshipId\"/>\n  <xsd:attribute name=\"dgmlayout\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"dgmnodekind\" type=\"xsd:integer\"/>\n  <xsd:attribute name=\"dgmlayoutmru\" type=\"ST_DiagramLayout\"/>\n  <xsd:attribute name=\"gfxdata\" type=\"xsd:base64Binary\"/>\n  <xsd:attribute name=\"tableproperties\" type=\"xsd:string\"/>\n  <xsd:attribute name=\"tablelimits\" type=\"xsd:string\"/>\n  <xsd:element name=\"shapedefaults\" type=\"CT_ShapeDefaults\"/>\n  <xsd:element name=\"shapelayout\" type=\"CT_ShapeLayout\"/>\n  <xsd:element name=\"signatureline\" type=\"CT_SignatureLine\"/>\n  <xsd:element name=\"ink\" type=\"CT_Ink\"/>\n  <xsd:element name=\"diagram\" type=\"CT_Diagram\"/>\n  <xsd:element name=\"equationxml\" type=\"CT_EquationXml\"/>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:all minOccurs=\"0\">\n      <xsd:element ref=\"v:fill\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:stroke\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:textbox\" minOccurs=\"0\"/>\n      <xsd:element ref=\"v:shadow\" minOccurs=\"0\"/>\n      <xsd:element ref=\"skew\" minOccurs=\"0\"/>\n      <xsd:element ref=\"extrusion\" minOccurs=\"0\"/>\n      <xsd:element ref=\"callout\" minOccurs=\"0\"/>\n      <xsd:element ref=\"lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"colormru\" minOccurs=\"0\" type=\"CT_ColorMru\"/>\n      <xsd:element name=\"colormenu\" minOccurs=\"0\" type=\"CT_ColorMenu\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"spidmax\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"style\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"stroke\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"allowincell\" form=\"qualified\" type=\"s:ST_TrueFalse\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ink\">\n    <xsd:sequence/>\n    <xsd:attribute name=\"i\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"annotation\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"contentType\" type=\"ST_ContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SignatureLine\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"issignatureline\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"id\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"provid\" type=\"s:ST_Guid\"/>\n    <xsd:attribute name=\"signinginstructionsset\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"allowcomments\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"showsigndate\" type=\"s:ST_TrueFalse\"/>\n    <xsd:attribute name=\"suggestedsigner\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigner2\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"suggestedsigneremail\" type=\"xsd:string\" form=\"qualified\"/>\n    <xsd:attribute name=\"signinginstructions\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"addlxml\" type=\"xsd:string\"/>\n    <xsd:attribute name=\"sigprovurl\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeLayout\">\n    <xsd:all>\n      <xsd:element name=\"idmap\" type=\"CT_IdMap\" minOccurs=\"0\"/>\n      <xsd:element name=\"regrouptable\" type=\"CT_RegroupTable\" minOccurs=\"0\"/>\n      <xsd:element name=\"rules\" type=\"CT_Rules\" minOccurs=\"0\"/>\n    </xsd:all>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_IdMap\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"data\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RegroupTable\">\n    <xsd:sequence>\n      <xsd:element name=\"entry\" type=\"CT_Entry\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Entry\">\n    <xsd:attribute name=\"new\" type=\"xsd:int\" use=\"optional\"/>\n    <xsd:attribute name=\"old\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rules\">\n    <xsd:sequence>\n      <xsd:element name=\"r\" type=\"CT_R\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:element name=\"proxy\" type=\"CT_Proxy\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n    <xsd:attribute name=\"type\" type=\"ST_RType\" use=\"optional\"/>\n    <xsd:attribute name=\"how\" type=\"ST_How\" use=\"optional\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Proxy\">\n    <xsd:attribute name=\"start\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"end\" type=\"s:ST_TrueFalseBlank\" use=\"optional\" default=\"false\"/>\n    <xsd:attribute name=\"idref\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"connectloc\" type=\"xsd:int\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Diagram\">\n    <xsd:sequence>\n      <xsd:element name=\"relationtable\" type=\"CT_RelationTable\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"dgmstyle\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"autoformat\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"reverse\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autolayout\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscalex\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmscaley\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmfontsize\" type=\"xsd:integer\" use=\"optional\"/>\n    <xsd:attribute name=\"constrainbounds\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"dgmbasetextscale\" type=\"xsd:integer\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EquationXml\">\n    <xsd:sequence>\n      <xsd:any namespace=\"##any\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"contentType\" type=\"ST_AlternateMathContentType\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_AlternateMathContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RelationTable\">\n    <xsd:sequence>\n      <xsd:element name=\"rel\" type=\"CT_Relation\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Relation\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"idsrc\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"iddest\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"idcntr\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMru\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"colors\" type=\"xsd:string\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ColorMenu\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"strokecolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"fillcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"shadowcolor\" type=\"s:ST_ColorType\"/>\n    <xsd:attribute name=\"extrusioncolor\" type=\"s:ST_ColorType\"/>\n  </xsd:complexType>\n  <xsd:element name=\"skew\" type=\"CT_Skew\"/>\n  <xsd:element name=\"extrusion\" type=\"CT_Extrusion\"/>\n  <xsd:element name=\"callout\" type=\"CT_Callout\"/>\n  <xsd:element name=\"lock\" type=\"CT_Lock\"/>\n  <xsd:element name=\"OLEObject\" type=\"CT_OLEObject\"/>\n  <xsd:element name=\"complex\" type=\"CT_Complex\"/>\n  <xsd:element name=\"left\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"top\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"right\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"bottom\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"column\" type=\"CT_StrokeChild\"/>\n  <xsd:element name=\"clippath\" type=\"CT_ClipPath\"/>\n  <xsd:element name=\"fill\" type=\"CT_Fill\"/>\n  <xsd:complexType name=\"CT_Skew\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"offset\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"origin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"matrix\" type=\"xsd:string\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Extrusion\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"ST_ExtrusionType\" default=\"parallel\" use=\"optional\"/>\n    <xsd:attribute name=\"render\" type=\"ST_ExtrusionRender\" default=\"solid\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpointorigin\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"viewpoint\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"plane\" type=\"ST_ExtrusionPlane\" default=\"XY\" use=\"optional\"/>\n    <xsd:attribute name=\"skewangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"skewamt\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"foredepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"backdepth\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientation\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"orientationangle\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"lockrotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"autorotationcenter\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationcenter\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"rotationangle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"colormode\" type=\"ST_ColorMode\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"shininess\" type=\"xsd:float\" use=\"optional\"/>\n    <xsd:attribute name=\"specularity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"diffusity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"metal\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"edge\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"facet\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightface\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"brightness\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"lightposition2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightlevel2\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lightharsh2\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Callout\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"type\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"gap\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"angle\" type=\"ST_Angle\" use=\"optional\"/>\n    <xsd:attribute name=\"dropauto\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"drop\" type=\"ST_CalloutDrop\" use=\"optional\"/>\n    <xsd:attribute name=\"distance\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"lengthspecified\" type=\"s:ST_TrueFalse\" default=\"f\" use=\"optional\"/>\n    <xsd:attribute name=\"length\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"accentbar\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"textborder\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusx\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"minusy\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"position\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"selection\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"grouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"ungrouping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"rotation\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"cropping\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"verticies\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"adjusthandles\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"text\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"aspectratio\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"shapetype\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OLEObject\">\n    <xsd:sequence>\n      <xsd:element name=\"LinkType\" type=\"ST_OLELinkType\" minOccurs=\"0\"/>\n      <xsd:element name=\"LockedField\" type=\"s:ST_TrueFalseBlank\" minOccurs=\"0\"/>\n      <xsd:element name=\"FieldCodes\" type=\"xsd:string\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"Type\" type=\"ST_OLEType\" use=\"optional\"/>\n    <xsd:attribute name=\"ProgID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"ShapeID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"DrawAspect\" type=\"ST_OLEDrawAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"ObjectID\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"UpdateMode\" type=\"ST_OLEUpdateMode\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Complex\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StrokeChild\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"on\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"weight\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"color2\" type=\"s:ST_ColorType\" use=\"optional\"/>\n    <xsd:attribute name=\"opacity\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"linestyle\" type=\"v:ST_StrokeLineStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"miterlimit\" type=\"xsd:decimal\" use=\"optional\"/>\n    <xsd:attribute name=\"joinstyle\" type=\"v:ST_StrokeJoinStyle\" use=\"optional\"/>\n    <xsd:attribute name=\"endcap\" type=\"v:ST_StrokeEndCap\" use=\"optional\"/>\n    <xsd:attribute name=\"dashstyle\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"insetpen\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"filltype\" type=\"v:ST_FillType\" use=\"optional\"/>\n    <xsd:attribute name=\"src\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imageaspect\" type=\"v:ST_ImageAspect\" use=\"optional\"/>\n    <xsd:attribute name=\"imagesize\" type=\"xsd:string\" use=\"optional\"/>\n    <xsd:attribute name=\"imagealignshape\" type=\"s:ST_TrueFalse\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"startarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrow\" type=\"v:ST_StrokeArrowType\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowwidth\" type=\"v:ST_StrokeArrowWidth\" use=\"optional\"/>\n    <xsd:attribute name=\"endarrowlength\" type=\"v:ST_StrokeArrowLength\" use=\"optional\"/>\n    <xsd:attribute ref=\"href\"/>\n    <xsd:attribute ref=\"althref\"/>\n    <xsd:attribute ref=\"title\"/>\n    <xsd:attribute ref=\"forcedash\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ClipPath\">\n    <xsd:attribute name=\"v\" type=\"xsd:string\" use=\"required\" form=\"qualified\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Fill\">\n    <xsd:attributeGroup ref=\"v:AG_Ext\"/>\n    <xsd:attribute name=\"type\" type=\"ST_FillType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"arc\"/>\n      <xsd:enumeration value=\"callout\"/>\n      <xsd:enumeration value=\"connector\"/>\n      <xsd:enumeration value=\"align\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_How\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"middle\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BWMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"color\"/>\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"grayScale\"/>\n      <xsd:enumeration value=\"lightGrayscale\"/>\n      <xsd:enumeration value=\"inverseGray\"/>\n      <xsd:enumeration value=\"grayOutline\"/>\n      <xsd:enumeration value=\"highContrast\"/>\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"hide\"/>\n      <xsd:enumeration value=\"undrawn\"/>\n      <xsd:enumeration value=\"blackTextAndLines\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ScreenSize\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544,376\"/>\n      <xsd:enumeration value=\"640,480\"/>\n      <xsd:enumeration value=\"720,512\"/>\n      <xsd:enumeration value=\"800,600\"/>\n      <xsd:enumeration value=\"1024,768\"/>\n      <xsd:enumeration value=\"1152,862\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InsetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ColorMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ContentType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DiagramLayout\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:enumeration value=\"0\"/>\n      <xsd:enumeration value=\"1\"/>\n      <xsd:enumeration value=\"2\"/>\n      <xsd:enumeration value=\"3\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"perspective\"/>\n      <xsd:enumeration value=\"parallel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionRender\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"wireFrame\"/>\n      <xsd:enumeration value=\"boundingCube\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ExtrusionPlane\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"XY\"/>\n      <xsd:enumeration value=\"ZX\"/>\n      <xsd:enumeration value=\"YZ\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Angle\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"30\"/>\n      <xsd:enumeration value=\"45\"/>\n      <xsd:enumeration value=\"60\"/>\n      <xsd:enumeration value=\"90\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutDrop\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_CalloutPlacement\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"user\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectorType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"straight\"/>\n      <xsd:enumeration value=\"elbow\"/>\n      <xsd:enumeration value=\"curved\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HrAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"center\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ConnectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"rect\"/>\n      <xsd:enumeration value=\"segments\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLELinkType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Embed\"/>\n      <xsd:enumeration value=\"Link\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Content\"/>\n      <xsd:enumeration value=\"Icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_OLEUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Always\"/>\n      <xsd:enumeration value=\"OnCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FillType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"gradientCenter\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"pattern\"/>\n      <xsd:enumeration value=\"tile\"/>\n      <xsd:enumeration value=\"frame\"/>\n      <xsd:enumeration value=\"gradientUnscaled\"/>\n      <xsd:enumeration value=\"gradientRadial\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"background\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:powerpoint\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:powerpoint\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"iscomment\" type=\"CT_Empty\"/>\n  <xsd:element name=\"textdata\" type=\"CT_Rel\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute name=\"id\" type=\"xsd:string\"/>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:excel\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:excel\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:element name=\"ClientData\" type=\"CT_ClientData\"/>\n  <xsd:complexType name=\"CT_ClientData\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"MoveWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SizeWithCells\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Anchor\" type=\"xsd:string\"/>\n      <xsd:element name=\"Locked\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DefaultSize\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"PrintObject\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Disabled\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoFill\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoPict\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaMacro\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextHAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"TextVAlign\" type=\"xsd:string\"/>\n      <xsd:element name=\"LockText\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"JustLastX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SecretEdit\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Default\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Help\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Cancel\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dismiss\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Accel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Accel2\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Row\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Column\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Visible\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RowHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ColHidden\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VTEdit\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MultiLine\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"VScroll\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ValidIds\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaRange\" type=\"xsd:string\"/>\n      <xsd:element name=\"WidthMin\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Sel\" type=\"xsd:integer\"/>\n      <xsd:element name=\"NoThreeD2\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"SelType\" type=\"xsd:string\"/>\n      <xsd:element name=\"MultiSel\" type=\"xsd:string\"/>\n      <xsd:element name=\"LCT\" type=\"xsd:string\"/>\n      <xsd:element name=\"ListItem\" type=\"xsd:string\"/>\n      <xsd:element name=\"DropStyle\" type=\"xsd:string\"/>\n      <xsd:element name=\"Colored\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DropLines\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Checked\" type=\"xsd:integer\"/>\n      <xsd:element name=\"FmlaLink\" type=\"xsd:string\"/>\n      <xsd:element name=\"FmlaPict\" type=\"xsd:string\"/>\n      <xsd:element name=\"NoThreeD\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FirstButton\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"FmlaGroup\" type=\"xsd:string\"/>\n      <xsd:element name=\"Val\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Min\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Max\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Inc\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Page\" type=\"xsd:integer\"/>\n      <xsd:element name=\"Horiz\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"Dx\" type=\"xsd:integer\"/>\n      <xsd:element name=\"MapOCX\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"CF\" type=\"ST_CF\"/>\n      <xsd:element name=\"Camera\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"RecalcAlways\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"AutoScale\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"DDE\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"UIObj\" type=\"s:ST_TrueFalseBlank\"/>\n      <xsd:element name=\"ScriptText\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptExtended\" type=\"xsd:string\"/>\n      <xsd:element name=\"ScriptLanguage\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"ScriptLocation\" type=\"xsd:nonNegativeInteger\"/>\n      <xsd:element name=\"FmlaTxbx\" type=\"xsd:string\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"ObjectType\" type=\"ST_ObjectType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CF\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_ObjectType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"Button\"/>\n      <xsd:enumeration value=\"Checkbox\"/>\n      <xsd:enumeration value=\"Dialog\"/>\n      <xsd:enumeration value=\"Drop\"/>\n      <xsd:enumeration value=\"Edit\"/>\n      <xsd:enumeration value=\"GBox\"/>\n      <xsd:enumeration value=\"Label\"/>\n      <xsd:enumeration value=\"LineA\"/>\n      <xsd:enumeration value=\"List\"/>\n      <xsd:enumeration value=\"Movie\"/>\n      <xsd:enumeration value=\"Note\"/>\n      <xsd:enumeration value=\"Pict\"/>\n      <xsd:enumeration value=\"Radio\"/>\n      <xsd:enumeration value=\"RectA\"/>\n      <xsd:enumeration value=\"Scroll\"/>\n      <xsd:enumeration value=\"Spin\"/>\n      <xsd:enumeration value=\"Shape\"/>\n      <xsd:enumeration value=\"Group\"/>\n      <xsd:enumeration value=\"Rect\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-microsoft-com:office:word\"\n  targetNamespace=\"urn:schemas-microsoft-com:office:word\" elementFormDefault=\"qualified\"\n  attributeFormDefault=\"unqualified\">\n  <xsd:element name=\"bordertop\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderleft\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderright\" type=\"CT_Border\"/>\n  <xsd:element name=\"borderbottom\" type=\"CT_Border\"/>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"type\" type=\"ST_BorderType\" use=\"optional\"/>\n    <xsd:attribute name=\"width\" type=\"xsd:positiveInteger\" use=\"optional\"/>\n    <xsd:attribute name=\"shadow\" type=\"ST_BorderShadow\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"wrap\" type=\"CT_Wrap\"/>\n  <xsd:complexType name=\"CT_Wrap\">\n    <xsd:attribute name=\"type\" type=\"ST_WrapType\" use=\"optional\"/>\n    <xsd:attribute name=\"side\" type=\"ST_WrapSide\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorx\" type=\"ST_HorizontalAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"anchory\" type=\"ST_VerticalAnchor\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:element name=\"anchorlock\" type=\"CT_AnchorLock\"/>\n  <xsd:complexType name=\"CT_AnchorLock\"/>\n  <xsd:simpleType name=\"ST_BorderType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"hairline\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotDot\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmall\"/>\n      <xsd:enumeration value=\"thickThinSmall\"/>\n      <xsd:enumeration value=\"thickBetweenThinSmall\"/>\n      <xsd:enumeration value=\"thinThick\"/>\n      <xsd:enumeration value=\"thickThin\"/>\n      <xsd:enumeration value=\"thickBetweenThin\"/>\n      <xsd:enumeration value=\"thinThickLarge\"/>\n      <xsd:enumeration value=\"thickThinLarge\"/>\n      <xsd:enumeration value=\"thickBetweenThinLarge\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashedSmall\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"HTMLOutset\"/>\n      <xsd:enumeration value=\"HTMLInset\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BorderShadow\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"t\"/>\n      <xsd:enumeration value=\"true\"/>\n      <xsd:enumeration value=\"f\"/>\n      <xsd:enumeration value=\"false\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"topAndBottom\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_WrapSide\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"largest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HorizontalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"char\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VerticalAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"line\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n  xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n  xmlns:sl=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n  xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n  xmlns=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n  xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n  xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\"\n  targetNamespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" schemaLocation=\"../mce/mc.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"\n    schemaLocation=\"dml-wordprocessingDrawing.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"\n    schemaLocation=\"shared-math.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    schemaLocation=\"shared-relationshipReference.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\"\n    schemaLocation=\"shared-commonSimpleTypes.xsd\"/>\n  <xsd:import namespace=\"http://schemas.openxmlformats.org/schemaLibrary/2006/main\"\n    schemaLocation=\"shared-customXmlSchemaProperties.xsd\"/>\n  <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n  <xsd:complexType name=\"CT_Empty\"/>\n  <xsd:complexType name=\"CT_OnOff\">\n    <xsd:attribute name=\"val\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LongHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"4\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LongHexNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_LongHexNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ShortHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UcharHexNumber\">\n    <xsd:restriction base=\"xsd:hexBinary\">\n      <xsd:length value=\"1\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Charset\">\n    <xsd:attribute name=\"val\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"characterSet\" type=\"s:ST_String\" use=\"optional\" default=\"ISO-8859-1\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DecimalNumberOrPercent\">\n    <xsd:union memberTypes=\"ST_UnqualifiedPercentage s:ST_Percentage\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_UnqualifiedPercentage\">\n    <xsd:restriction base=\"xsd:decimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DecimalNumber\">\n    <xsd:restriction base=\"xsd:integer\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_UnsignedDecimalNumber\">\n    <xsd:attribute name=\"val\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DecimalNumberOrPrecent\">\n    <xsd:attribute name=\"val\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedTwipsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedTwipsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PixelsMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PixelsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HpsMeasure\">\n    <xsd:union memberTypes=\"s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_HpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SignedHpsMeasure\">\n    <xsd:union memberTypes=\"xsd:integer s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SignedHpsMeasure\">\n    <xsd:attribute name=\"val\" type=\"ST_SignedHpsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DateTime\">\n    <xsd:restriction base=\"xsd:dateTime\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_MacroName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"33\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MacroName\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MacroName\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EighthPointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PointMeasure\">\n    <xsd:restriction base=\"s:ST_UnsignedDecimalNumber\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_String\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextScale\">\n    <xsd:union memberTypes=\"ST_TextScalePercent ST_TextScaleDecimal\"/>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScalePercent\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern value=\"0*(600|([0-5]?[0-9]?[0-9]))%\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TextScaleDecimal\">\n    <xsd:restriction base=\"xsd:integer\">\n      <xsd:minInclusive value=\"0\"/>\n      <xsd:maxInclusive value=\"600\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextScale\">\n    <xsd:attribute name=\"val\" type=\"ST_TextScale\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HighlightColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"black\"/>\n      <xsd:enumeration value=\"blue\"/>\n      <xsd:enumeration value=\"cyan\"/>\n      <xsd:enumeration value=\"green\"/>\n      <xsd:enumeration value=\"magenta\"/>\n      <xsd:enumeration value=\"red\"/>\n      <xsd:enumeration value=\"yellow\"/>\n      <xsd:enumeration value=\"white\"/>\n      <xsd:enumeration value=\"darkBlue\"/>\n      <xsd:enumeration value=\"darkCyan\"/>\n      <xsd:enumeration value=\"darkGreen\"/>\n      <xsd:enumeration value=\"darkMagenta\"/>\n      <xsd:enumeration value=\"darkRed\"/>\n      <xsd:enumeration value=\"darkYellow\"/>\n      <xsd:enumeration value=\"darkGray\"/>\n      <xsd:enumeration value=\"lightGray\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Highlight\">\n    <xsd:attribute name=\"val\" type=\"ST_HighlightColor\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HexColorAuto\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HexColor\">\n    <xsd:union memberTypes=\"ST_HexColorAuto s:ST_HexColorRGB\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Color\">\n    <xsd:attribute name=\"val\" type=\"ST_HexColor\" use=\"required\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lang\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Guid\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Guid\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Underline\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"words\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dottedHeavy\"/>\n      <xsd:enumeration value=\"dash\"/>\n      <xsd:enumeration value=\"dashedHeavy\"/>\n      <xsd:enumeration value=\"dashLong\"/>\n      <xsd:enumeration value=\"dashLongHeavy\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dashDotHeavy\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"dashDotDotHeavy\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"wavyHeavy\"/>\n      <xsd:enumeration value=\"wavyDouble\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Underline\">\n    <xsd:attribute name=\"val\" type=\"ST_Underline\" use=\"optional\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextEffect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"blinkBackground\"/>\n      <xsd:enumeration value=\"lights\"/>\n      <xsd:enumeration value=\"antsBlack\"/>\n      <xsd:enumeration value=\"antsRed\"/>\n      <xsd:enumeration value=\"shimmer\"/>\n      <xsd:enumeration value=\"sparkle\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextEffect\">\n    <xsd:attribute name=\"val\" type=\"ST_TextEffect\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Border\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"single\"/>\n      <xsd:enumeration value=\"thick\"/>\n      <xsd:enumeration value=\"double\"/>\n      <xsd:enumeration value=\"dotted\"/>\n      <xsd:enumeration value=\"dashed\"/>\n      <xsd:enumeration value=\"dotDash\"/>\n      <xsd:enumeration value=\"dotDotDash\"/>\n      <xsd:enumeration value=\"triple\"/>\n      <xsd:enumeration value=\"thinThickSmallGap\"/>\n      <xsd:enumeration value=\"thickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickThinSmallGap\"/>\n      <xsd:enumeration value=\"thinThickMediumGap\"/>\n      <xsd:enumeration value=\"thickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickThinMediumGap\"/>\n      <xsd:enumeration value=\"thinThickLargeGap\"/>\n      <xsd:enumeration value=\"thickThinLargeGap\"/>\n      <xsd:enumeration value=\"thinThickThinLargeGap\"/>\n      <xsd:enumeration value=\"wave\"/>\n      <xsd:enumeration value=\"doubleWave\"/>\n      <xsd:enumeration value=\"dashSmallGap\"/>\n      <xsd:enumeration value=\"dashDotStroked\"/>\n      <xsd:enumeration value=\"threeDEmboss\"/>\n      <xsd:enumeration value=\"threeDEngrave\"/>\n      <xsd:enumeration value=\"outset\"/>\n      <xsd:enumeration value=\"inset\"/>\n      <xsd:enumeration value=\"apples\"/>\n      <xsd:enumeration value=\"archedScallops\"/>\n      <xsd:enumeration value=\"babyPacifier\"/>\n      <xsd:enumeration value=\"babyRattle\"/>\n      <xsd:enumeration value=\"balloons3Colors\"/>\n      <xsd:enumeration value=\"balloonsHotAir\"/>\n      <xsd:enumeration value=\"basicBlackDashes\"/>\n      <xsd:enumeration value=\"basicBlackDots\"/>\n      <xsd:enumeration value=\"basicBlackSquares\"/>\n      <xsd:enumeration value=\"basicThinLines\"/>\n      <xsd:enumeration value=\"basicWhiteDashes\"/>\n      <xsd:enumeration value=\"basicWhiteDots\"/>\n      <xsd:enumeration value=\"basicWhiteSquares\"/>\n      <xsd:enumeration value=\"basicWideInline\"/>\n      <xsd:enumeration value=\"basicWideMidline\"/>\n      <xsd:enumeration value=\"basicWideOutline\"/>\n      <xsd:enumeration value=\"bats\"/>\n      <xsd:enumeration value=\"birds\"/>\n      <xsd:enumeration value=\"birdsFlight\"/>\n      <xsd:enumeration value=\"cabins\"/>\n      <xsd:enumeration value=\"cakeSlice\"/>\n      <xsd:enumeration value=\"candyCorn\"/>\n      <xsd:enumeration value=\"celticKnotwork\"/>\n      <xsd:enumeration value=\"certificateBanner\"/>\n      <xsd:enumeration value=\"chainLink\"/>\n      <xsd:enumeration value=\"champagneBottle\"/>\n      <xsd:enumeration value=\"checkedBarBlack\"/>\n      <xsd:enumeration value=\"checkedBarColor\"/>\n      <xsd:enumeration value=\"checkered\"/>\n      <xsd:enumeration value=\"christmasTree\"/>\n      <xsd:enumeration value=\"circlesLines\"/>\n      <xsd:enumeration value=\"circlesRectangles\"/>\n      <xsd:enumeration value=\"classicalWave\"/>\n      <xsd:enumeration value=\"clocks\"/>\n      <xsd:enumeration value=\"compass\"/>\n      <xsd:enumeration value=\"confetti\"/>\n      <xsd:enumeration value=\"confettiGrays\"/>\n      <xsd:enumeration value=\"confettiOutline\"/>\n      <xsd:enumeration value=\"confettiStreamers\"/>\n      <xsd:enumeration value=\"confettiWhite\"/>\n      <xsd:enumeration value=\"cornerTriangles\"/>\n      <xsd:enumeration value=\"couponCutoutDashes\"/>\n      <xsd:enumeration value=\"couponCutoutDots\"/>\n      <xsd:enumeration value=\"crazyMaze\"/>\n      <xsd:enumeration value=\"creaturesButterfly\"/>\n      <xsd:enumeration value=\"creaturesFish\"/>\n      <xsd:enumeration value=\"creaturesInsects\"/>\n      <xsd:enumeration value=\"creaturesLadyBug\"/>\n      <xsd:enumeration value=\"crossStitch\"/>\n      <xsd:enumeration value=\"cup\"/>\n      <xsd:enumeration value=\"decoArch\"/>\n      <xsd:enumeration value=\"decoArchColor\"/>\n      <xsd:enumeration value=\"decoBlocks\"/>\n      <xsd:enumeration value=\"diamondsGray\"/>\n      <xsd:enumeration value=\"doubleD\"/>\n      <xsd:enumeration value=\"doubleDiamonds\"/>\n      <xsd:enumeration value=\"earth1\"/>\n      <xsd:enumeration value=\"earth2\"/>\n      <xsd:enumeration value=\"earth3\"/>\n      <xsd:enumeration value=\"eclipsingSquares1\"/>\n      <xsd:enumeration value=\"eclipsingSquares2\"/>\n      <xsd:enumeration value=\"eggsBlack\"/>\n      <xsd:enumeration value=\"fans\"/>\n      <xsd:enumeration value=\"film\"/>\n      <xsd:enumeration value=\"firecrackers\"/>\n      <xsd:enumeration value=\"flowersBlockPrint\"/>\n      <xsd:enumeration value=\"flowersDaisies\"/>\n      <xsd:enumeration value=\"flowersModern1\"/>\n      <xsd:enumeration value=\"flowersModern2\"/>\n      <xsd:enumeration value=\"flowersPansy\"/>\n      <xsd:enumeration value=\"flowersRedRose\"/>\n      <xsd:enumeration value=\"flowersRoses\"/>\n      <xsd:enumeration value=\"flowersTeacup\"/>\n      <xsd:enumeration value=\"flowersTiny\"/>\n      <xsd:enumeration value=\"gems\"/>\n      <xsd:enumeration value=\"gingerbreadMan\"/>\n      <xsd:enumeration value=\"gradient\"/>\n      <xsd:enumeration value=\"handmade1\"/>\n      <xsd:enumeration value=\"handmade2\"/>\n      <xsd:enumeration value=\"heartBalloon\"/>\n      <xsd:enumeration value=\"heartGray\"/>\n      <xsd:enumeration value=\"hearts\"/>\n      <xsd:enumeration value=\"heebieJeebies\"/>\n      <xsd:enumeration value=\"holly\"/>\n      <xsd:enumeration value=\"houseFunky\"/>\n      <xsd:enumeration value=\"hypnotic\"/>\n      <xsd:enumeration value=\"iceCreamCones\"/>\n      <xsd:enumeration value=\"lightBulb\"/>\n      <xsd:enumeration value=\"lightning1\"/>\n      <xsd:enumeration value=\"lightning2\"/>\n      <xsd:enumeration value=\"mapPins\"/>\n      <xsd:enumeration value=\"mapleLeaf\"/>\n      <xsd:enumeration value=\"mapleMuffins\"/>\n      <xsd:enumeration value=\"marquee\"/>\n      <xsd:enumeration value=\"marqueeToothed\"/>\n      <xsd:enumeration value=\"moons\"/>\n      <xsd:enumeration value=\"mosaic\"/>\n      <xsd:enumeration value=\"musicNotes\"/>\n      <xsd:enumeration value=\"northwest\"/>\n      <xsd:enumeration value=\"ovals\"/>\n      <xsd:enumeration value=\"packages\"/>\n      <xsd:enumeration value=\"palmsBlack\"/>\n      <xsd:enumeration value=\"palmsColor\"/>\n      <xsd:enumeration value=\"paperClips\"/>\n      <xsd:enumeration value=\"papyrus\"/>\n      <xsd:enumeration value=\"partyFavor\"/>\n      <xsd:enumeration value=\"partyGlass\"/>\n      <xsd:enumeration value=\"pencils\"/>\n      <xsd:enumeration value=\"people\"/>\n      <xsd:enumeration value=\"peopleWaving\"/>\n      <xsd:enumeration value=\"peopleHats\"/>\n      <xsd:enumeration value=\"poinsettias\"/>\n      <xsd:enumeration value=\"postageStamp\"/>\n      <xsd:enumeration value=\"pumpkin1\"/>\n      <xsd:enumeration value=\"pushPinNote2\"/>\n      <xsd:enumeration value=\"pushPinNote1\"/>\n      <xsd:enumeration value=\"pyramids\"/>\n      <xsd:enumeration value=\"pyramidsAbove\"/>\n      <xsd:enumeration value=\"quadrants\"/>\n      <xsd:enumeration value=\"rings\"/>\n      <xsd:enumeration value=\"safari\"/>\n      <xsd:enumeration value=\"sawtooth\"/>\n      <xsd:enumeration value=\"sawtoothGray\"/>\n      <xsd:enumeration value=\"scaredCat\"/>\n      <xsd:enumeration value=\"seattle\"/>\n      <xsd:enumeration value=\"shadowedSquares\"/>\n      <xsd:enumeration value=\"sharksTeeth\"/>\n      <xsd:enumeration value=\"shorebirdTracks\"/>\n      <xsd:enumeration value=\"skyrocket\"/>\n      <xsd:enumeration value=\"snowflakeFancy\"/>\n      <xsd:enumeration value=\"snowflakes\"/>\n      <xsd:enumeration value=\"sombrero\"/>\n      <xsd:enumeration value=\"southwest\"/>\n      <xsd:enumeration value=\"stars\"/>\n      <xsd:enumeration value=\"starsTop\"/>\n      <xsd:enumeration value=\"stars3d\"/>\n      <xsd:enumeration value=\"starsBlack\"/>\n      <xsd:enumeration value=\"starsShadowed\"/>\n      <xsd:enumeration value=\"sun\"/>\n      <xsd:enumeration value=\"swirligig\"/>\n      <xsd:enumeration value=\"tornPaper\"/>\n      <xsd:enumeration value=\"tornPaperBlack\"/>\n      <xsd:enumeration value=\"trees\"/>\n      <xsd:enumeration value=\"triangleParty\"/>\n      <xsd:enumeration value=\"triangles\"/>\n      <xsd:enumeration value=\"triangle1\"/>\n      <xsd:enumeration value=\"triangle2\"/>\n      <xsd:enumeration value=\"triangleCircle1\"/>\n      <xsd:enumeration value=\"triangleCircle2\"/>\n      <xsd:enumeration value=\"shapes1\"/>\n      <xsd:enumeration value=\"shapes2\"/>\n      <xsd:enumeration value=\"twistedLines1\"/>\n      <xsd:enumeration value=\"twistedLines2\"/>\n      <xsd:enumeration value=\"vine\"/>\n      <xsd:enumeration value=\"waveline\"/>\n      <xsd:enumeration value=\"weavingAngles\"/>\n      <xsd:enumeration value=\"weavingBraid\"/>\n      <xsd:enumeration value=\"weavingRibbon\"/>\n      <xsd:enumeration value=\"weavingStrips\"/>\n      <xsd:enumeration value=\"whiteFlowers\"/>\n      <xsd:enumeration value=\"woodwork\"/>\n      <xsd:enumeration value=\"xIllusions\"/>\n      <xsd:enumeration value=\"zanyTriangles\"/>\n      <xsd:enumeration value=\"zigZag\"/>\n      <xsd:enumeration value=\"zigZagStitch\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Border\">\n    <xsd:attribute name=\"val\" type=\"ST_Border\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"sz\" type=\"ST_EighthPointMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"ST_PointMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"shadow\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"frame\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Shd\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"solid\"/>\n      <xsd:enumeration value=\"horzStripe\"/>\n      <xsd:enumeration value=\"vertStripe\"/>\n      <xsd:enumeration value=\"reverseDiagStripe\"/>\n      <xsd:enumeration value=\"diagStripe\"/>\n      <xsd:enumeration value=\"horzCross\"/>\n      <xsd:enumeration value=\"diagCross\"/>\n      <xsd:enumeration value=\"thinHorzStripe\"/>\n      <xsd:enumeration value=\"thinVertStripe\"/>\n      <xsd:enumeration value=\"thinReverseDiagStripe\"/>\n      <xsd:enumeration value=\"thinDiagStripe\"/>\n      <xsd:enumeration value=\"thinHorzCross\"/>\n      <xsd:enumeration value=\"thinDiagCross\"/>\n      <xsd:enumeration value=\"pct5\"/>\n      <xsd:enumeration value=\"pct10\"/>\n      <xsd:enumeration value=\"pct12\"/>\n      <xsd:enumeration value=\"pct15\"/>\n      <xsd:enumeration value=\"pct20\"/>\n      <xsd:enumeration value=\"pct25\"/>\n      <xsd:enumeration value=\"pct30\"/>\n      <xsd:enumeration value=\"pct35\"/>\n      <xsd:enumeration value=\"pct37\"/>\n      <xsd:enumeration value=\"pct40\"/>\n      <xsd:enumeration value=\"pct45\"/>\n      <xsd:enumeration value=\"pct50\"/>\n      <xsd:enumeration value=\"pct55\"/>\n      <xsd:enumeration value=\"pct60\"/>\n      <xsd:enumeration value=\"pct62\"/>\n      <xsd:enumeration value=\"pct65\"/>\n      <xsd:enumeration value=\"pct70\"/>\n      <xsd:enumeration value=\"pct75\"/>\n      <xsd:enumeration value=\"pct80\"/>\n      <xsd:enumeration value=\"pct85\"/>\n      <xsd:enumeration value=\"pct87\"/>\n      <xsd:enumeration value=\"pct90\"/>\n      <xsd:enumeration value=\"pct95\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Shd\">\n    <xsd:attribute name=\"val\" type=\"ST_Shd\" use=\"required\"/>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"fill\" type=\"ST_HexColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFill\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeFillShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_VerticalAlignRun\">\n    <xsd:attribute name=\"val\" type=\"s:ST_VerticalAlignRun\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FitText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Em\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"comma\"/>\n      <xsd:enumeration value=\"circle\"/>\n      <xsd:enumeration value=\"underDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Em\">\n    <xsd:attribute name=\"val\" type=\"ST_Em\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Language\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_Lang\" use=\"optional\"/>\n    <xsd:attribute name=\"bidi\" type=\"s:ST_Lang\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CombineBrackets\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"round\"/>\n      <xsd:enumeration value=\"square\"/>\n      <xsd:enumeration value=\"angle\"/>\n      <xsd:enumeration value=\"curly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EastAsianLayout\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"combine\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"combineBrackets\" type=\"ST_CombineBrackets\" use=\"optional\"/>\n    <xsd:attribute name=\"vert\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"vertCompress\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HeightRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Wrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"notBeside\"/>\n      <xsd:enumeration value=\"around\"/>\n      <xsd:enumeration value=\"tight\"/>\n      <xsd:enumeration value=\"through\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_VAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_HAnchor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"page\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DropCap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"drop\"/>\n      <xsd:enumeration value=\"margin\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FramePr\">\n    <xsd:attribute name=\"dropCap\" type=\"ST_DropCap\" use=\"optional\"/>\n    <xsd:attribute name=\"lines\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"vSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hSpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"wrap\" type=\"ST_Wrap\" use=\"optional\"/>\n    <xsd:attribute name=\"hAnchor\" type=\"ST_HAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"vAnchor\" type=\"ST_VAnchor\" use=\"optional\"/>\n    <xsd:attribute name=\"x\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"xAlign\" type=\"s:ST_XAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"y\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"yAlign\" type=\"s:ST_YAlign\" use=\"optional\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\" use=\"optional\"/>\n    <xsd:attribute name=\"anchorLock\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TabJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clear\"/>\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"bar\"/>\n      <xsd:enumeration value=\"num\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_TabTlc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"heavy\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TabStop\">\n    <xsd:attribute name=\"val\" type=\"ST_TabJc\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_TabTlc\" use=\"optional\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LineSpacingRule\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"auto\"/>\n      <xsd:enumeration value=\"exact\"/>\n      <xsd:enumeration value=\"atLeast\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Spacing\">\n    <xsd:attribute name=\"before\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"beforeAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"after\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterLines\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"afterAutospacing\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"line\" type=\"ST_SignedTwipsMeasure\" use=\"optional\" default=\"0\"/>\n    <xsd:attribute name=\"lineRule\" type=\"ST_LineSpacingRule\" use=\"optional\" default=\"auto\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ind\">\n    <xsd:attribute name=\"start\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"startChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"end\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"endChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"left\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"leftChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"right\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"rightChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"hanging\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"hangingChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLine\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"firstLineChars\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Jc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"start\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"mediumKashida\"/>\n      <xsd:enumeration value=\"distribute\"/>\n      <xsd:enumeration value=\"numTab\"/>\n      <xsd:enumeration value=\"highKashida\"/>\n      <xsd:enumeration value=\"lowKashida\"/>\n      <xsd:enumeration value=\"thaiDistribute\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_JcTable\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"end\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"start\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Jc\">\n    <xsd:attribute name=\"val\" type=\"ST_Jc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_JcTable\">\n    <xsd:attribute name=\"val\" type=\"ST_JcTable\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_View\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"print\"/>\n      <xsd:enumeration value=\"outline\"/>\n      <xsd:enumeration value=\"masterPages\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"web\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_View\">\n    <xsd:attribute name=\"val\" type=\"ST_View\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Zoom\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"fullPage\"/>\n      <xsd:enumeration value=\"bestFit\"/>\n      <xsd:enumeration value=\"textFit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Zoom\">\n    <xsd:attribute name=\"val\" type=\"ST_Zoom\" use=\"optional\"/>\n    <xsd:attribute name=\"percent\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WritingStyle\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"vendorID\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"dllVersion\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"nlCheck\" type=\"s:ST_OnOff\" use=\"optional\" default=\"off\"/>\n    <xsd:attribute name=\"checkStyle\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"appName\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Proof\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"clean\"/>\n      <xsd:enumeration value=\"dirty\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Proof\">\n    <xsd:attribute name=\"spelling\" type=\"ST_Proof\" use=\"optional\"/>\n    <xsd:attribute name=\"grammar\" type=\"ST_Proof\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocType\">\n    <xsd:attribute name=\"val\" type=\"ST_DocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocProtect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"readOnly\"/>\n      <xsd:enumeration value=\"comments\"/>\n      <xsd:enumeration value=\"trackedChanges\"/>\n      <xsd:enumeration value=\"forms\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:attributeGroup name=\"AG_Password\">\n    <xsd:attribute name=\"algorithmName\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"hashValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"saltValue\" type=\"xsd:base64Binary\" use=\"optional\"/>\n    <xsd:attribute name=\"spinCount\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:attributeGroup>\n  <xsd:attributeGroup name=\"AG_TransitionalPassword\">\n    <xsd:attribute name=\"cryptProviderType\" type=\"s:ST_CryptProv\"/>\n    <xsd:attribute name=\"cryptAlgorithmClass\" type=\"s:ST_AlgClass\"/>\n    <xsd:attribute name=\"cryptAlgorithmType\" type=\"s:ST_AlgType\"/>\n    <xsd:attribute name=\"cryptAlgorithmSid\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptSpinCount\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"cryptProvider\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"algIdExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"algIdExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cryptProviderTypeExt\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"cryptProviderTypeExtSource\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hash\" type=\"xsd:base64Binary\"/>\n    <xsd:attribute name=\"salt\" type=\"xsd:base64Binary\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_DocProtect\">\n    <xsd:attribute name=\"edit\" type=\"ST_DocProtect\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"enforcement\" type=\"s:ST_OnOff\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDocType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"catalog\"/>\n      <xsd:enumeration value=\"envelopes\"/>\n      <xsd:enumeration value=\"mailingLabels\"/>\n      <xsd:enumeration value=\"formLetters\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDocType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDocType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDataType\">\n    <xsd:restriction base=\"xsd:string\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDataType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDataType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeDest\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newDocument\"/>\n      <xsd:enumeration value=\"printer\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"fax\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeDest\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeDest\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeOdsoFMDFieldType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"null\"/>\n      <xsd:enumeration value=\"dbColumn\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeOdsoFMDFieldType\">\n    <xsd:attribute name=\"val\" type=\"ST_MailMergeOdsoFMDFieldType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangesView\">\n    <xsd:attribute name=\"markup\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"comments\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"insDel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"formatting\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"inkAnnotations\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Kinsoku\">\n    <xsd:attribute name=\"lang\" type=\"s:ST_Lang\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextDirection\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tb\"/>\n      <xsd:enumeration value=\"rl\"/>\n      <xsd:enumeration value=\"lr\"/>\n      <xsd:enumeration value=\"tbV\"/>\n      <xsd:enumeration value=\"rlV\"/>\n      <xsd:enumeration value=\"lrV\"/>\n      <xsd:enumeration value=\"btLr\"/>\n      <xsd:enumeration value=\"lrTb\"/>\n      <xsd:enumeration value=\"lrTbV\"/>\n      <xsd:enumeration value=\"tbLrV\"/>\n      <xsd:enumeration value=\"tbRl\"/>\n      <xsd:enumeration value=\"tbRlV\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextDirection\">\n    <xsd:attribute name=\"val\" type=\"ST_TextDirection\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"baseline\"/>\n      <xsd:enumeration value=\"bottom\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextAlignment\">\n    <xsd:attribute name=\"val\" type=\"ST_TextAlignment\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DisplacedByCustomXml\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"next\"/>\n      <xsd:enumeration value=\"prev\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_AnnotationVMerge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"cont\"/>\n      <xsd:enumeration value=\"rest\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Markup\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CellMergeTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"vMerge\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n        <xsd:attribute name=\"vMergeOrig\" type=\"ST_AnnotationVMerge\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MarkupRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BookmarkRange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_MarkupRange\">\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Bookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_BookmarkRange\">\n        <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MoveBookmark\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Bookmark\">\n        <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n        <xsd:attribute name=\"date\" type=\"ST_DateTime\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comment\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"initials\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrackChangeNumbering\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:attribute name=\"original\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrEx\" type=\"CT_TblPrExBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPr\" type=\"CT_TcPrInner\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"trPr\" type=\"CT_TrPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Markup\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGrid\" type=\"CT_TblGridBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPrBase\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"pPr\" type=\"CT_PPrBase\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_RPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPrOriginal\" minOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RunTrackChange\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:group ref=\"EG_ContentRunContent\"/>\n          <xsd:group ref=\"m:EG_OMathMathElements\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContentMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_PContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_ContentRunContentBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_PContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_ContentRunContentBase\">\n    <xsd:choice>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_CellMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"cellIns\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellDel\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"cellMerge\" type=\"CT_CellMergeTrackChange\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RangeMarkupElements\">\n    <xsd:choice>\n      <xsd:element name=\"bookmarkStart\" type=\"CT_Bookmark\"/>\n      <xsd:element name=\"bookmarkEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveFromRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveFromRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"moveToRangeStart\" type=\"CT_MoveBookmark\"/>\n      <xsd:element name=\"moveToRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeStart\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"commentRangeEnd\" type=\"CT_MarkupRange\"/>\n      <xsd:element name=\"customXmlInsRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlInsRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlDelRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlDelRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveFromRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveFromRangeEnd\" type=\"CT_Markup\"/>\n      <xsd:element name=\"customXmlMoveToRangeStart\" type=\"CT_TrackChange\"/>\n      <xsd:element name=\"customXmlMoveToRangeEnd\" type=\"CT_Markup\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_NumPr\">\n    <xsd:sequence>\n      <xsd:element name=\"ilvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"between\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bar\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tabs\">\n    <xsd:sequence>\n      <xsd:element name=\"tab\" type=\"CT_TabStop\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TextboxTightWrap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"allLines\"/>\n      <xsd:enumeration value=\"firstAndLastLine\"/>\n      <xsd:enumeration value=\"firstLineOnly\"/>\n      <xsd:enumeration value=\"lastLineOnly\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TextboxTightWrap\">\n    <xsd:attribute name=\"val\" type=\"ST_TextboxTightWrap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepNext\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"keepLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pageBreakBefore\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"framePr\" type=\"CT_FramePr\" minOccurs=\"0\"/>\n      <xsd:element name=\"widowControl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"numPr\" type=\"CT_NumPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressLineNumbers\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pBdr\" type=\"CT_PBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabs\" type=\"CT_Tabs\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressAutoHyphens\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"kinsoku\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wordWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"overflowPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"topLinePunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDE\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceDN\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustRightInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacing\" type=\"CT_Spacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"ind\" type=\"CT_Ind\" minOccurs=\"0\"/>\n      <xsd:element name=\"contextualSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorIndents\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressOverlap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"jc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"textAlignment\" type=\"CT_TextAlignment\" minOccurs=\"0\"/>\n      <xsd:element name=\"textboxTightWrap\" type=\"CT_TextboxTightWrap\" minOccurs=\"0\"/>\n      <xsd:element name=\"outlineLvl\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"rPr\" type=\"CT_ParaRPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"sectPr\" type=\"CT_SectPr\" minOccurs=\"0\"/>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrGeneral\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"pPrChange\" type=\"CT_PPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Control\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeid\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Background\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"color\" type=\"ST_HexColor\" use=\"optional\" default=\"auto\"/>\n    <xsd:attribute name=\"themeColor\" type=\"ST_ThemeColor\" use=\"optional\"/>\n    <xsd:attribute name=\"themeTint\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"themeShade\" type=\"ST_UcharHexNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Rel\">\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Object\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\">\n        <xsd:element name=\"control\" type=\"CT_Control\"/>\n        <xsd:element name=\"objectLink\" type=\"CT_ObjectLink\"/>\n        <xsd:element name=\"objectEmbed\" type=\"CT_ObjectEmbed\"/>\n        <xsd:element name=\"movie\" type=\"CT_Rel\"/>\n      </xsd:choice>\n    </xsd:sequence>\n    <xsd:attribute name=\"dxaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"dyaOrig\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Picture\">\n    <xsd:sequence>\n      <xsd:sequence maxOccurs=\"unbounded\">\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:vml\" minOccurs=\"0\"\n          maxOccurs=\"unbounded\"/>\n        <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n          minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:sequence>\n      <xsd:element name=\"movie\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"control\" type=\"CT_Control\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ObjectEmbed\">\n    <xsd:attribute name=\"drawAspect\" type=\"ST_ObjectDrawAspect\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\" use=\"required\"/>\n    <xsd:attribute name=\"progId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"shapeId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"fieldCodes\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectDrawAspect\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"icon\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ObjectLink\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_ObjectEmbed\">\n        <xsd:attribute name=\"updateMode\" type=\"ST_ObjectUpdateMode\" use=\"required\"/>\n        <xsd:attribute name=\"lockedField\" type=\"s:ST_OnOff\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ObjectUpdateMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"always\"/>\n      <xsd:enumeration value=\"onCall\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Drawing\">\n    <xsd:choice minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element ref=\"wp:anchor\" minOccurs=\"0\"/>\n      <xsd:element ref=\"wp:inline\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SimpleField\">\n    <xsd:sequence>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"instr\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FldCharType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"begin\"/>\n      <xsd:enumeration value=\"separate\"/>\n      <xsd:enumeration value=\"end\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_InfoTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"autoText\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFHelpTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"256\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFStatusTextVal\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"140\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFName\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:maxLength value=\"65\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FFTextType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"regular\"/>\n      <xsd:enumeration value=\"number\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"currentTime\"/>\n      <xsd:enumeration value=\"currentDate\"/>\n      <xsd:enumeration value=\"calculated\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FFTextType\">\n    <xsd:attribute name=\"val\" type=\"ST_FFTextType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFName\">\n    <xsd:attribute name=\"val\" type=\"ST_FFName\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FldChar\">\n    <xsd:choice>\n      <xsd:element name=\"fldData\" type=\"CT_Text\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"ffData\" type=\"CT_FFData\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"numberingChange\" type=\"CT_TrackChangeNumbering\" minOccurs=\"0\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"fldCharType\" type=\"ST_FldCharType\" use=\"required\"/>\n    <xsd:attribute name=\"fldLock\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"dirty\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Hyperlink\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"tgtFrame\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"tooltip\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"docLocation\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"history\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"anchor\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute ref=\"r:id\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFData\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"name\" type=\"CT_FFName\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"enabled\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"calcOnExit\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"entryMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"exitMacro\" type=\"CT_MacroName\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"helpText\" type=\"CT_FFHelpText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"statusText\" type=\"CT_FFStatusText\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:choice>\n        <xsd:element name=\"checkBox\" type=\"CT_FFCheckBox\"/>\n        <xsd:element name=\"ddList\" type=\"CT_FFDDList\"/>\n        <xsd:element name=\"textInput\" type=\"CT_FFTextInput\"/>\n      </xsd:choice>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFHelpText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFHelpTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFStatusText\">\n    <xsd:attribute name=\"type\" type=\"ST_InfoTextType\"/>\n    <xsd:attribute name=\"val\" type=\"ST_FFStatusTextVal\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFCheckBox\">\n    <xsd:sequence>\n      <xsd:choice>\n        <xsd:element name=\"size\" type=\"CT_HpsMeasure\"/>\n        <xsd:element name=\"sizeAuto\" type=\"CT_OnOff\"/>\n      </xsd:choice>\n      <xsd:element name=\"default\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFDDList\">\n    <xsd:sequence>\n      <xsd:element name=\"result\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"listEntry\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FFTextInput\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_FFTextType\" minOccurs=\"0\"/>\n      <xsd:element name=\"default\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"maxLength\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"format\" type=\"CT_String\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SectionMark\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nextPage\"/>\n      <xsd:enumeration value=\"nextColumn\"/>\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"evenPage\"/>\n      <xsd:enumeration value=\"oddPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SectType\">\n    <xsd:attribute name=\"val\" type=\"ST_SectionMark\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PaperSource\">\n    <xsd:attribute name=\"first\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"other\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_NumberFormat\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decimal\"/>\n      <xsd:enumeration value=\"upperRoman\"/>\n      <xsd:enumeration value=\"lowerRoman\"/>\n      <xsd:enumeration value=\"upperLetter\"/>\n      <xsd:enumeration value=\"lowerLetter\"/>\n      <xsd:enumeration value=\"ordinal\"/>\n      <xsd:enumeration value=\"cardinalText\"/>\n      <xsd:enumeration value=\"ordinalText\"/>\n      <xsd:enumeration value=\"hex\"/>\n      <xsd:enumeration value=\"chicago\"/>\n      <xsd:enumeration value=\"ideographDigital\"/>\n      <xsd:enumeration value=\"japaneseCounting\"/>\n      <xsd:enumeration value=\"aiueo\"/>\n      <xsd:enumeration value=\"iroha\"/>\n      <xsd:enumeration value=\"decimalFullWidth\"/>\n      <xsd:enumeration value=\"decimalHalfWidth\"/>\n      <xsd:enumeration value=\"japaneseLegal\"/>\n      <xsd:enumeration value=\"japaneseDigitalTenThousand\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircle\"/>\n      <xsd:enumeration value=\"decimalFullWidth2\"/>\n      <xsd:enumeration value=\"aiueoFullWidth\"/>\n      <xsd:enumeration value=\"irohaFullWidth\"/>\n      <xsd:enumeration value=\"decimalZero\"/>\n      <xsd:enumeration value=\"bullet\"/>\n      <xsd:enumeration value=\"ganada\"/>\n      <xsd:enumeration value=\"chosung\"/>\n      <xsd:enumeration value=\"decimalEnclosedFullstop\"/>\n      <xsd:enumeration value=\"decimalEnclosedParen\"/>\n      <xsd:enumeration value=\"decimalEnclosedCircleChinese\"/>\n      <xsd:enumeration value=\"ideographEnclosedCircle\"/>\n      <xsd:enumeration value=\"ideographTraditional\"/>\n      <xsd:enumeration value=\"ideographZodiac\"/>\n      <xsd:enumeration value=\"ideographZodiacTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCounting\"/>\n      <xsd:enumeration value=\"ideographLegalTraditional\"/>\n      <xsd:enumeration value=\"taiwaneseCountingThousand\"/>\n      <xsd:enumeration value=\"taiwaneseDigital\"/>\n      <xsd:enumeration value=\"chineseCounting\"/>\n      <xsd:enumeration value=\"chineseLegalSimplified\"/>\n      <xsd:enumeration value=\"chineseCountingThousand\"/>\n      <xsd:enumeration value=\"koreanDigital\"/>\n      <xsd:enumeration value=\"koreanCounting\"/>\n      <xsd:enumeration value=\"koreanLegal\"/>\n      <xsd:enumeration value=\"koreanDigital2\"/>\n      <xsd:enumeration value=\"vietnameseCounting\"/>\n      <xsd:enumeration value=\"russianLower\"/>\n      <xsd:enumeration value=\"russianUpper\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"numberInDash\"/>\n      <xsd:enumeration value=\"hebrew1\"/>\n      <xsd:enumeration value=\"hebrew2\"/>\n      <xsd:enumeration value=\"arabicAlpha\"/>\n      <xsd:enumeration value=\"arabicAbjad\"/>\n      <xsd:enumeration value=\"hindiVowels\"/>\n      <xsd:enumeration value=\"hindiConsonants\"/>\n      <xsd:enumeration value=\"hindiNumbers\"/>\n      <xsd:enumeration value=\"hindiCounting\"/>\n      <xsd:enumeration value=\"thaiLetters\"/>\n      <xsd:enumeration value=\"thaiNumbers\"/>\n      <xsd:enumeration value=\"thaiCounting\"/>\n      <xsd:enumeration value=\"bahtText\"/>\n      <xsd:enumeration value=\"dollarText\"/>\n      <xsd:enumeration value=\"custom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageOrientation\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"portrait\"/>\n      <xsd:enumeration value=\"landscape\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageSz\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"h\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"orient\" type=\"ST_PageOrientation\" use=\"optional\"/>\n    <xsd:attribute name=\"code\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageMar\">\n    <xsd:attribute name=\"top\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"right\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"bottom\" type=\"ST_SignedTwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"left\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"header\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"footer\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"gutter\" type=\"s:ST_TwipsMeasure\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PageBorderZOrder\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"front\"/>\n      <xsd:enumeration value=\"back\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderDisplay\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"allPages\"/>\n      <xsd:enumeration value=\"firstPage\"/>\n      <xsd:enumeration value=\"notFirstPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PageBorderOffset\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"text\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PageBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TopPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_BottomPageBorder\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_PageBorder\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"zOrder\" type=\"ST_PageBorderZOrder\" use=\"optional\" default=\"front\"/>\n    <xsd:attribute name=\"display\" type=\"ST_PageBorderDisplay\" use=\"optional\"/>\n    <xsd:attribute name=\"offsetFrom\" type=\"ST_PageBorderOffset\" use=\"optional\" default=\"text\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Border\">\n        <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BottomPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:bottomLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:bottomRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TopPageBorder\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_PageBorder\">\n        <xsd:attribute ref=\"r:topLeft\" use=\"optional\"/>\n        <xsd:attribute ref=\"r:topRight\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ChapterSep\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"period\"/>\n      <xsd:enumeration value=\"colon\"/>\n      <xsd:enumeration value=\"emDash\"/>\n      <xsd:enumeration value=\"enDash\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_LineNumberRestart\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"newPage\"/>\n      <xsd:enumeration value=\"newSection\"/>\n      <xsd:enumeration value=\"continuous\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LineNumber\">\n    <xsd:attribute name=\"countBy\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"distance\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"restart\" type=\"ST_LineNumberRestart\" use=\"optional\" default=\"newPage\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PageNumber\">\n    <xsd:attribute name=\"fmt\" type=\"ST_NumberFormat\" use=\"optional\" default=\"decimal\"/>\n    <xsd:attribute name=\"start\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapStyle\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"chapSep\" type=\"ST_ChapterSep\" use=\"optional\" default=\"hyphen\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Column\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"0\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Columns\">\n    <xsd:sequence minOccurs=\"0\">\n      <xsd:element name=\"col\" type=\"CT_Column\" maxOccurs=\"45\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"equalWidth\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"space\" type=\"s:ST_TwipsMeasure\" use=\"optional\" default=\"720\"/>\n    <xsd:attribute name=\"num\" type=\"ST_DecimalNumber\" use=\"optional\" default=\"1\"/>\n    <xsd:attribute name=\"sep\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_VerticalJc\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"top\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"both\"/>\n      <xsd:enumeration value=\"bottom\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VerticalJc\">\n    <xsd:attribute name=\"val\" type=\"ST_VerticalJc\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocGrid\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"lines\"/>\n      <xsd:enumeration value=\"linesAndChars\"/>\n      <xsd:enumeration value=\"snapToChars\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocGrid\">\n    <xsd:attribute name=\"type\" type=\"ST_DocGrid\"/>\n    <xsd:attribute name=\"linePitch\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"charSpace\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_HdrFtr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"even\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"first\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_FtnEdn\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"separator\"/>\n      <xsd:enumeration value=\"continuationSeparator\"/>\n      <xsd:enumeration value=\"continuationNotice\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_HdrFtrRef\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"type\" type=\"ST_HdrFtr\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_HdrFtrReferences\">\n    <xsd:choice>\n      <xsd:element name=\"headerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n      <xsd:element name=\"footerReference\" type=\"CT_HdrFtrRef\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_HdrFtr\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_SectPrContents\">\n    <xsd:sequence>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_SectType\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgSz\" type=\"CT_PageSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgMar\" type=\"CT_PageMar\" minOccurs=\"0\"/>\n      <xsd:element name=\"paperSrc\" type=\"CT_PaperSource\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgBorders\" type=\"CT_PageBorders\" minOccurs=\"0\"/>\n      <xsd:element name=\"lnNumType\" type=\"CT_LineNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNumType\" type=\"CT_PageNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"cols\" type=\"CT_Columns\" minOccurs=\"0\"/>\n      <xsd:element name=\"formProt\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"noEndnote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"titlePg\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\"/>\n      <xsd:element name=\"bidi\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rtlGutter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"docGrid\" type=\"CT_DocGrid\" minOccurs=\"0\"/>\n      <xsd:element name=\"printerSettings\" type=\"CT_Rel\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:attributeGroup name=\"AG_SectPrAttributes\">\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidSect\" type=\"ST_LongHexNumber\"/>\n  </xsd:attributeGroup>\n  <xsd:complexType name=\"CT_SectPrBase\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SectPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_HdrFtrReferences\" minOccurs=\"0\" maxOccurs=\"6\"/>\n      <xsd:group ref=\"EG_SectPrContents\" minOccurs=\"0\"/>\n      <xsd:element name=\"sectPrChange\" type=\"CT_SectPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attributeGroup ref=\"AG_SectPrAttributes\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_BrType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"page\"/>\n      <xsd:enumeration value=\"column\"/>\n      <xsd:enumeration value=\"textWrapping\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_BrClear\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"all\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Br\">\n    <xsd:attribute name=\"type\" type=\"ST_BrType\" use=\"optional\"/>\n    <xsd:attribute name=\"clear\" type=\"ST_BrClear\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_PTabAlignment\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabRelativeTo\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"margin\"/>\n      <xsd:enumeration value=\"indent\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_PTabLeader\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"dot\"/>\n      <xsd:enumeration value=\"hyphen\"/>\n      <xsd:enumeration value=\"underscore\"/>\n      <xsd:enumeration value=\"middleDot\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_PTab\">\n    <xsd:attribute name=\"alignment\" type=\"ST_PTabAlignment\" use=\"required\"/>\n    <xsd:attribute name=\"relativeTo\" type=\"ST_PTabRelativeTo\" use=\"required\"/>\n    <xsd:attribute name=\"leader\" type=\"ST_PTabLeader\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Sym\">\n    <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"char\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ProofErr\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"spellStart\"/>\n      <xsd:enumeration value=\"spellEnd\"/>\n      <xsd:enumeration value=\"gramStart\"/>\n      <xsd:enumeration value=\"gramEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ProofErr\">\n    <xsd:attribute name=\"type\" type=\"ST_ProofErr\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdGrp\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"everyone\"/>\n      <xsd:enumeration value=\"administrators\"/>\n      <xsd:enumeration value=\"contributors\"/>\n      <xsd:enumeration value=\"editors\"/>\n      <xsd:enumeration value=\"owners\"/>\n      <xsd:enumeration value=\"current\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Perm\">\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"displacedByCustomXml\" type=\"ST_DisplacedByCustomXml\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PermStart\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Perm\">\n        <xsd:attribute name=\"edGrp\" type=\"ST_EdGrp\" use=\"optional\"/>\n        <xsd:attribute name=\"ed\" type=\"s:ST_String\" use=\"optional\"/>\n        <xsd:attribute name=\"colFirst\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n        <xsd:attribute name=\"colLast\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Text\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"s:ST_String\">\n        <xsd:attribute ref=\"xml:space\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RunInnerContent\">\n    <xsd:choice>\n      <xsd:element name=\"br\" type=\"CT_Br\"/>\n      <xsd:element name=\"t\" type=\"CT_Text\"/>\n      <xsd:element name=\"contentPart\" type=\"CT_Rel\"/>\n      <xsd:element name=\"delText\" type=\"CT_Text\"/>\n      <xsd:element name=\"instrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"delInstrText\" type=\"CT_Text\"/>\n      <xsd:element name=\"noBreakHyphen\" type=\"CT_Empty\"/>\n      <xsd:element name=\"softHyphen\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearShort\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"dayLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"monthLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"yearLong\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"annotationRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnoteRef\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"separator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"continuationSeparator\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"sym\" type=\"CT_Sym\" minOccurs=\"0\"/>\n      <xsd:element name=\"pgNum\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"cr\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"tab\" type=\"CT_Empty\" minOccurs=\"0\"/>\n      <xsd:element name=\"object\" type=\"CT_Object\"/>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"fldChar\" type=\"CT_FldChar\"/>\n      <xsd:element name=\"ruby\" type=\"CT_Ruby\"/>\n      <xsd:element name=\"footnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"endnoteReference\" type=\"CT_FtnEdnRef\"/>\n      <xsd:element name=\"commentReference\" type=\"CT_Markup\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n      <xsd:element name=\"ptab\" type=\"CT_PTab\" minOccurs=\"0\"/>\n      <xsd:element name=\"lastRenderedPageBreak\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_R\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RunInnerContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Hint\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"eastAsia\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_Theme\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"majorEastAsia\"/>\n      <xsd:enumeration value=\"majorBidi\"/>\n      <xsd:enumeration value=\"majorAscii\"/>\n      <xsd:enumeration value=\"majorHAnsi\"/>\n      <xsd:enumeration value=\"minorEastAsia\"/>\n      <xsd:enumeration value=\"minorBidi\"/>\n      <xsd:enumeration value=\"minorAscii\"/>\n      <xsd:enumeration value=\"minorHAnsi\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Fonts\">\n    <xsd:attribute name=\"hint\" type=\"ST_Hint\"/>\n    <xsd:attribute name=\"ascii\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"hAnsi\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"eastAsia\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"cs\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"asciiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"hAnsiTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"eastAsiaTheme\" type=\"ST_Theme\"/>\n    <xsd:attribute name=\"cstheme\" type=\"ST_Theme\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPrBase\">\n    <xsd:choice>\n      <xsd:element name=\"rStyle\" type=\"CT_String\"/>\n      <xsd:element name=\"rFonts\" type=\"CT_Fonts\"/>\n      <xsd:element name=\"b\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"bCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"i\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"iCs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"caps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"smallCaps\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"strike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"dstrike\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"outline\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"shadow\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"emboss\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"imprint\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"noProof\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"snapToGrid\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"vanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"webHidden\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\"/>\n      <xsd:element name=\"spacing\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"w\" type=\"CT_TextScale\"/>\n      <xsd:element name=\"kern\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"position\" type=\"CT_SignedHpsMeasure\"/>\n      <xsd:element name=\"sz\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"szCs\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"highlight\" type=\"CT_Highlight\"/>\n      <xsd:element name=\"u\" type=\"CT_Underline\"/>\n      <xsd:element name=\"effect\" type=\"CT_TextEffect\"/>\n      <xsd:element name=\"bdr\" type=\"CT_Border\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\"/>\n      <xsd:element name=\"fitText\" type=\"CT_FitText\"/>\n      <xsd:element name=\"vertAlign\" type=\"CT_VerticalAlignRun\"/>\n      <xsd:element name=\"rtl\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"cs\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"em\" type=\"CT_Em\"/>\n      <xsd:element name=\"lang\" type=\"CT_Language\"/>\n      <xsd:element name=\"eastAsianLayout\" type=\"CT_EastAsianLayout\"/>\n      <xsd:element name=\"specVanish\" type=\"CT_OnOff\"/>\n      <xsd:element name=\"oMath\" type=\"CT_OnOff\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrContent\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_RPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrContent\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:group name=\"EG_RPrMath\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_RPr\"/>\n      <xsd:element name=\"ins\" type=\"CT_MathCtrlIns\"/>\n      <xsd:element name=\"del\" type=\"CT_MathCtrlDel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_MathCtrlIns\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"del\" type=\"CT_RPrChange\" minOccurs=\"1\"/>\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MathCtrlDel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrackChange\">\n        <xsd:choice minOccurs=\"0\">\n          <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"1\"/>\n        </xsd:choice>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPrOriginal\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ParaRPr\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_ParaRPrTrackChanges\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_RPrBase\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"rPrChange\" type=\"CT_ParaRPrChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ParaRPrTrackChanges\">\n    <xsd:sequence>\n      <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_AltChunk\">\n    <xsd:sequence>\n      <xsd:element name=\"altChunkPr\" type=\"CT_AltChunkPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AltChunkPr\">\n    <xsd:sequence>\n      <xsd:element name=\"matchSrc\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RubyAlign\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"center\"/>\n      <xsd:enumeration value=\"distributeLetter\"/>\n      <xsd:enumeration value=\"distributeSpace\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n      <xsd:enumeration value=\"rightVertical\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_RubyAlign\">\n    <xsd:attribute name=\"val\" type=\"ST_RubyAlign\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RubyPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyAlign\" type=\"CT_RubyAlign\"/>\n      <xsd:element name=\"hps\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsRaise\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"hpsBaseText\" type=\"CT_HpsMeasure\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\"/>\n      <xsd:element name=\"dirty\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_RubyContent\">\n    <xsd:choice>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_RubyContent\">\n    <xsd:group ref=\"EG_RubyContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Ruby\">\n    <xsd:sequence>\n      <xsd:element name=\"rubyPr\" type=\"CT_RubyPr\"/>\n      <xsd:element name=\"rt\" type=\"CT_RubyContent\"/>\n      <xsd:element name=\"rubyBase\" type=\"CT_RubyContent\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Lock\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sdtLocked\"/>\n      <xsd:enumeration value=\"contentLocked\"/>\n      <xsd:enumeration value=\"unlocked\"/>\n      <xsd:enumeration value=\"sdtContentLocked\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Lock\">\n    <xsd:attribute name=\"val\" type=\"ST_Lock\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtListItem\">\n    <xsd:attribute name=\"displayText\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"value\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_SdtDateMappingType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"date\"/>\n      <xsd:enumeration value=\"dateTime\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtDateMappingType\">\n    <xsd:attribute name=\"val\" type=\"ST_SdtDateMappingType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CalendarType\">\n    <xsd:attribute name=\"val\" type=\"s:ST_CalendarType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDate\">\n    <xsd:sequence>\n      <xsd:element name=\"dateFormat\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"storeMappedDataAs\" type=\"CT_SdtDateMappingType\" minOccurs=\"0\"/>\n      <xsd:element name=\"calendar\" type=\"CT_CalendarType\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"fullDate\" type=\"ST_DateTime\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtComboBox\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartGallery\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartCategory\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartUnique\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtDropDownList\">\n    <xsd:sequence>\n      <xsd:element name=\"listItem\" type=\"CT_SdtListItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"lastValue\" type=\"s:ST_String\" use=\"optional\" default=\"\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Placeholder\">\n    <xsd:sequence>\n      <xsd:element name=\"docPart\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtText\">\n    <xsd:attribute name=\"multiLine\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DataBinding\">\n    <xsd:attribute name=\"prefixMappings\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"xpath\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"storeItemID\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtPr\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"alias\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tag\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"id\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lock\" type=\"CT_Lock\" minOccurs=\"0\"/>\n      <xsd:element name=\"placeholder\" type=\"CT_Placeholder\" minOccurs=\"0\"/>\n      <xsd:element name=\"temporary\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showingPlcHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataBinding\" type=\"CT_DataBinding\" minOccurs=\"0\"/>\n      <xsd:element name=\"label\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"tabIndex\" type=\"CT_UnsignedDecimalNumber\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n        <xsd:element name=\"equation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"comboBox\" type=\"CT_SdtComboBox\"/>\n        <xsd:element name=\"date\" type=\"CT_SdtDate\"/>\n        <xsd:element name=\"docPartObj\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"docPartList\" type=\"CT_SdtDocPart\"/>\n        <xsd:element name=\"dropDownList\" type=\"CT_SdtDropDownList\"/>\n        <xsd:element name=\"picture\" type=\"CT_Empty\"/>\n        <xsd:element name=\"richText\" type=\"CT_Empty\"/>\n        <xsd:element name=\"text\" type=\"CT_SdtText\"/>\n        <xsd:element name=\"citation\" type=\"CT_Empty\"/>\n        <xsd:element name=\"group\" type=\"CT_Empty\"/>\n        <xsd:element name=\"bibliography\" type=\"CT_Empty\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtEndPr\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRunContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRun\"/>\n      <xsd:element name=\"smartTag\" type=\"CT_SmartTagRun\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRun\"/>\n      <xsd:element name=\"dir\" type=\"CT_DirContentRun\"/>\n      <xsd:element name=\"bdo\" type=\"CT_BdoContentRun\"/>\n      <xsd:element name=\"r\" type=\"CT_R\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_DirContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_BdoContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    <xsd:attribute name=\"val\" type=\"ST_Direction\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Direction\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"ltr\"/>\n      <xsd:enumeration value=\"rtl\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_SdtContentRun\">\n    <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentBlockContent\">\n    <xsd:choice>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlBlock\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtBlock\"/>\n      <xsd:element name=\"p\" type=\"CT_P\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tbl\" type=\"CT_Tbl\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentBlock\">\n    <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentRowContent\">\n    <xsd:choice>\n      <xsd:element name=\"tr\" type=\"CT_Row\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlRow\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtRow\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentRow\">\n    <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_ContentCellContent\">\n    <xsd:choice>\n      <xsd:element name=\"tc\" type=\"CT_Tc\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"customXml\" type=\"CT_CustomXmlCell\"/>\n      <xsd:element name=\"sdt\" type=\"CT_SdtCell\"/>\n      <xsd:group ref=\"EG_RunLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_SdtContentCell\">\n    <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentBlock\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRun\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRun\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtCell\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentCell\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SdtRow\">\n    <xsd:sequence>\n      <xsd:element name=\"sdtPr\" type=\"CT_SdtPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtEndPr\" type=\"CT_SdtEndPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sdtContent\" type=\"CT_SdtContentRow\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Attr\">\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRun\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagRun\">\n    <xsd:sequence>\n      <xsd:element name=\"smartTagPr\" type=\"CT_SmartTagPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlBlock\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlPr\">\n    <xsd:sequence>\n      <xsd:element name=\"placeholder\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlRow\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CustomXmlCell\">\n    <xsd:sequence>\n      <xsd:element name=\"customXmlPr\" type=\"CT_CustomXmlPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"element\" type=\"s:ST_XmlName\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SmartTagPr\">\n    <xsd:sequence>\n      <xsd:element name=\"attr\" type=\"CT_Attr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:group name=\"EG_PContent\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentRunContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"fldSimple\" type=\"CT_SimpleField\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"hyperlink\" type=\"CT_Hyperlink\"/>\n      <xsd:element name=\"subDoc\" type=\"CT_Rel\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_P\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPr\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_PContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidP\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidRDefault\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblWidth\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"nil\"/>\n      <xsd:enumeration value=\"pct\"/>\n      <xsd:enumeration value=\"dxa\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Height\">\n    <xsd:attribute name=\"val\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"hRule\" type=\"ST_HeightRule\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MeasurementOrPercent\">\n    <xsd:union memberTypes=\"ST_DecimalNumberOrPercent s:ST_UniversalMeasure\"/>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblWidth\">\n    <xsd:attribute name=\"w\" type=\"ST_MeasurementOrPercent\"/>\n    <xsd:attribute name=\"type\" type=\"ST_TblWidth\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridCol\">\n    <xsd:attribute name=\"w\" type=\"s:ST_TwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGridBase\">\n    <xsd:sequence>\n      <xsd:element name=\"gridCol\" type=\"CT_TblGridCol\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblGrid\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblGridBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblGridChange\" type=\"CT_TblGridChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tl2br\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"tr2bl\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Merge\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continue\"/>\n      <xsd:enumeration value=\"restart\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_VMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_HMerge\">\n    <xsd:attribute name=\"val\" type=\"ST_Merge\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gridSpan\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hMerge\" type=\"CT_HMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"vMerge\" type=\"CT_VMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcBorders\" type=\"CT_TcBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\"/>\n      <xsd:element name=\"noWrap\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tcMar\" type=\"CT_TcMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"textDirection\" type=\"CT_TextDirection\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcFitText\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"vAlign\" type=\"CT_VerticalJc\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"headers\" type=\"CT_Headers\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrInner\">\n        <xsd:sequence>\n          <xsd:element name=\"tcPrChange\" type=\"CT_TcPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TcPrInner\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TcPrBase\">\n        <xsd:sequence>\n          <xsd:group ref=\"EG_CellMarkupElements\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tc\">\n    <xsd:sequence>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Cnf\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:length value=\"12\"/>\n      <xsd:pattern value=\"[01]*\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Cnf\">\n    <xsd:attribute name=\"val\" type=\"ST_Cnf\"/>\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"oddHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"evenHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstRowLastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowFirstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRowLastColumn\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Headers\">\n    <xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"header\" type=\"CT_String\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPrBase\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:element name=\"cnfStyle\" type=\"CT_Cnf\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"divId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridBefore\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"gridAfter\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"wBefore\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"wAfter\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"cantSplit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"trHeight\" type=\"CT_Height\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TrPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TrPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"ins\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"del\" type=\"CT_TrackChange\" minOccurs=\"0\"/>\n          <xsd:element name=\"trPrChange\" type=\"CT_TrPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Row\">\n    <xsd:sequence>\n      <xsd:element name=\"tblPrEx\" type=\"CT_TblPrEx\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:group ref=\"EG_ContentCellContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"rsidRPr\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidR\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidDel\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"rsidTr\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblLayoutType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"autofit\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblLayoutType\">\n    <xsd:attribute name=\"type\" type=\"ST_TblLayoutType\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblOverlap\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"never\"/>\n      <xsd:enumeration value=\"overlap\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblOverlap\">\n    <xsd:attribute name=\"val\" type=\"ST_TblOverlap\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPPr\">\n    <xsd:attribute name=\"leftFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"rightFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"topFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"bottomFromText\" type=\"s:ST_TwipsMeasure\"/>\n    <xsd:attribute name=\"vertAnchor\" type=\"ST_VAnchor\"/>\n    <xsd:attribute name=\"horzAnchor\" type=\"ST_HAnchor\"/>\n    <xsd:attribute name=\"tblpXSpec\" type=\"s:ST_XAlign\"/>\n    <xsd:attribute name=\"tblpX\" type=\"ST_SignedTwipsMeasure\"/>\n    <xsd:attribute name=\"tblpYSpec\" type=\"s:ST_YAlign\"/>\n    <xsd:attribute name=\"tblpY\" type=\"ST_SignedTwipsMeasure\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblCellMar\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"start\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"left\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"end\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"right\" type=\"CT_TblWidth\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblBorders\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"start\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"end\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideH\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"insideV\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblpPr\" type=\"CT_TblPPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblOverlap\" type=\"CT_TblOverlap\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"bidiVisual\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleRowBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStyleColBandSize\" type=\"CT_DecimalNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCaption\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblDescription\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPr\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrChange\" type=\"CT_TblPrChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrExBase\">\n    <xsd:sequence>\n      <xsd:element name=\"tblW\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"jc\" type=\"CT_JcTable\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellSpacing\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblInd\" type=\"CT_TblWidth\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblBorders\" type=\"CT_TblBorders\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shd\" type=\"CT_Shd\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLayout\" type=\"CT_TblLayoutType\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblCellMar\" type=\"CT_TblCellMar\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblLook\" type=\"CT_TblLook\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblPrEx\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_TblPrExBase\">\n        <xsd:sequence>\n          <xsd:element name=\"tblPrExChange\" type=\"CT_TblPrExChange\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Tbl\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPr\"/>\n      <xsd:element name=\"tblGrid\" type=\"CT_TblGrid\"/>\n      <xsd:group ref=\"EG_ContentRowContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TblLook\">\n    <xsd:attribute name=\"firstRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastRow\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"firstColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"lastColumn\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noHBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"noVBand\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FtnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"pageBottom\"/>\n      <xsd:enumeration value=\"beneathText\"/>\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FtnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_FtnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_EdnPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"sectEnd\"/>\n      <xsd:enumeration value=\"docEnd\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_EdnPos\">\n    <xsd:attribute name=\"val\" type=\"ST_EdnPos\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumFmt\">\n    <xsd:attribute name=\"val\" type=\"ST_NumberFormat\" use=\"required\"/>\n    <xsd:attribute name=\"format\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_RestartNumber\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"continuous\"/>\n      <xsd:enumeration value=\"eachSect\"/>\n      <xsd:enumeration value=\"eachPage\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_NumRestart\">\n    <xsd:attribute name=\"val\" type=\"ST_RestartNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnRef\">\n    <xsd:attribute name=\"customMarkFollows\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" use=\"required\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdnSepRef\">\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnEdn\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_FtnEdn\" use=\"optional\"/>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:group name=\"EG_FtnEdnNumProps\">\n    <xsd:sequence>\n      <xsd:element name=\"numStart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numRestart\" type=\"CT_NumRestart\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:group>\n  <xsd:complexType name=\"CT_FtnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_FtnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnProps\">\n    <xsd:sequence>\n      <xsd:element name=\"pos\" type=\"CT_EdnPos\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:group ref=\"EG_FtnEdnNumProps\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FtnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_FtnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"footnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_EdnDocProps\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_EdnProps\">\n        <xsd:sequence>\n          <xsd:element name=\"endnote\" type=\"CT_FtnEdnSepRef\" minOccurs=\"0\" maxOccurs=\"3\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RecipientData\">\n    <xsd:sequence>\n      <xsd:element name=\"active\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"uniqueTag\" type=\"CT_Base64Binary\" minOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Base64Binary\">\n    <xsd:attribute name=\"val\" type=\"xsd:base64Binary\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Recipients\">\n    <xsd:sequence>\n      <xsd:element name=\"recipientData\" type=\"CT_RecipientData\" minOccurs=\"1\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"recipients\" type=\"CT_Recipients\"/>\n  <xsd:complexType name=\"CT_OdsoFieldMapData\">\n    <xsd:sequence>\n      <xsd:element name=\"type\" type=\"CT_MailMergeOdsoFMDFieldType\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mappedName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"column\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lid\" type=\"CT_Lang\" minOccurs=\"0\"/>\n      <xsd:element name=\"dynamicAddress\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MailMergeSourceType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"database\"/>\n      <xsd:enumeration value=\"addressBook\"/>\n      <xsd:enumeration value=\"document1\"/>\n      <xsd:enumeration value=\"document2\"/>\n      <xsd:enumeration value=\"text\"/>\n      <xsd:enumeration value=\"email\"/>\n      <xsd:enumeration value=\"native\"/>\n      <xsd:enumeration value=\"legacy\"/>\n      <xsd:enumeration value=\"master\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MailMergeSourceType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_MailMergeSourceType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Odso\">\n    <xsd:sequence>\n      <xsd:element name=\"udl\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"table\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"src\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"colDelim\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"type\" type=\"CT_MailMergeSourceType\" minOccurs=\"0\"/>\n      <xsd:element name=\"fHdr\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"fieldMapData\" type=\"CT_OdsoFieldMapData\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"recipientData\" type=\"CT_Rel\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_MailMerge\">\n    <xsd:sequence>\n      <xsd:element name=\"mainDocumentType\" type=\"CT_MailMergeDocType\" minOccurs=\"1\"/>\n      <xsd:element name=\"linkToQuery\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataType\" type=\"CT_MailMergeDataType\" minOccurs=\"1\"/>\n      <xsd:element name=\"connectString\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"query\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"dataSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"headerSource\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressBlankLines\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"destination\" type=\"CT_MailMergeDest\" minOccurs=\"0\"/>\n      <xsd:element name=\"addressFieldName\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailSubject\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailAsAttachment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"viewMergedData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeRecord\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"checkErrors\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"odso\" type=\"CT_Odso\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TargetScreenSz\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"544x376\"/>\n      <xsd:enumeration value=\"640x480\"/>\n      <xsd:enumeration value=\"720x512\"/>\n      <xsd:enumeration value=\"800x600\"/>\n      <xsd:enumeration value=\"1024x768\"/>\n      <xsd:enumeration value=\"1152x882\"/>\n      <xsd:enumeration value=\"1152x900\"/>\n      <xsd:enumeration value=\"1280x1024\"/>\n      <xsd:enumeration value=\"1600x1200\"/>\n      <xsd:enumeration value=\"1800x1440\"/>\n      <xsd:enumeration value=\"1920x1200\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TargetScreenSz\">\n    <xsd:attribute name=\"val\" type=\"ST_TargetScreenSz\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Compat\">\n    <xsd:sequence>\n      <xsd:element name=\"useSingleBorderforContiguousCells\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpJustification\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noTabHangInd\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLeading\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spaceForUL\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noColumnBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"balanceSingleByteDoubleByteWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noExtraLineSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotLeaveBackslashAlone\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ulTrailSpace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotExpandShiftReturn\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"spacingInWholePoints\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"lineWrapLikeWord6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printBodyTextBeforeHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printColBlack\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wpSpaceWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showBreaksInFrames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"subFontBySize\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressBottomSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpacingAtTopOfPage\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressTopSpacingWP\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suppressSpBfAfterPgBrk\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"swapBordersFacingPages\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"convMailMergeEsc\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"truncateFontHeightsLikeWP6\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mwSmallCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"usePrinterMetrics\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressParagraphBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"wrapTrailSpaces\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnoteLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"shapeLayoutLikeWW8\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignTablesRowByRow\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forgetLastTabAlignment\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"adjustLineHeightInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoSpaceLikeWord95\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noSpaceRaiseLower\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseHTMLParagraphAutoSpacing\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutRawTableWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"layoutTableRowsApart\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord97LineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakWrappedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSnapToGridInCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"selectFldWithFirstOrLastChar\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"applyBreakingRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotWrapTextWithPunct\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseEastAsianBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useWord2002TableStyleRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"growAutofit\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useFELayout\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useNormalStyleForList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseIndentAsNumberingTabStop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAltKinsokuLineBreakRules\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowSpaceOfSameStyleInTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSuppressIndentation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutofitConstrainedTables\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"autofitToFirstFixedWidthCell\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"underlineTabInNumList\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHangulFixedWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"splitPgBreakAndParaMark\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignCellWithSp\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotBreakConstrainedForcedTable\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotVertAlignInTxbx\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useAnsiKerningPairs\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"cachedColBalance\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"compatSetting\" type=\"CT_CompatSetting\" minOccurs=\"0\" maxOccurs=\"unbounded\"\n      />\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_CompatSetting\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"uri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVar\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocVars\">\n    <xsd:sequence>\n      <xsd:element name=\"docVar\" type=\"CT_DocVar\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocRsids\">\n    <xsd:sequence>\n      <xsd:element name=\"rsidRoot\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_CharacterSpacing\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"doNotCompress\"/>\n      <xsd:enumeration value=\"compressPunctuation\"/>\n      <xsd:enumeration value=\"compressPunctuationAndJapaneseKana\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_CharacterSpacing\">\n    <xsd:attribute name=\"val\" type=\"ST_CharacterSpacing\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_SaveThroughXslt\">\n    <xsd:attribute ref=\"r:id\" use=\"optional\"/>\n    <xsd:attribute name=\"solutionID\" type=\"s:ST_String\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_RPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_PPrDefault\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocDefaults\">\n    <xsd:sequence>\n      <xsd:element name=\"rPrDefault\" type=\"CT_RPrDefault\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPrDefault\" type=\"CT_PPrDefault\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_WmlColorSchemeIndex\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_ColorSchemeMapping\">\n    <xsd:attribute name=\"bg1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"bg2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"t2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent1\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent2\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent3\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent4\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent5\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"accent6\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"hyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n    <xsd:attribute name=\"followedHyperlink\" type=\"ST_WmlColorSchemeIndex\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ReadingModeInkLockDown\">\n    <xsd:attribute name=\"actualPg\" type=\"s:ST_OnOff\" use=\"required\"/>\n    <xsd:attribute name=\"w\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"h\" type=\"ST_PixelsMeasure\" use=\"required\"/>\n    <xsd:attribute name=\"fontSz\" type=\"ST_DecimalNumberOrPercent\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_WriteProtection\">\n    <xsd:attribute name=\"recommended\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attributeGroup ref=\"AG_Password\"/>\n    <xsd:attributeGroup ref=\"AG_TransitionalPassword\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Settings\">\n    <xsd:sequence>\n      <xsd:element name=\"writeProtection\" type=\"CT_WriteProtection\" minOccurs=\"0\"/>\n      <xsd:element name=\"view\" type=\"CT_View\" minOccurs=\"0\"/>\n      <xsd:element name=\"zoom\" type=\"CT_Zoom\" minOccurs=\"0\"/>\n      <xsd:element name=\"removePersonalInformation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"removeDateAndTime\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDisplayPageBoundaries\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayBackgroundShape\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printPostScriptOverText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFractionalCharacterWidth\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"printFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedTrueTypeFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"embedSystemFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSubsetFonts\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveFormsData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"mirrorMargins\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alignBordersAndEdges\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundHeader\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bordersDoNotSurroundFooter\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"gutterAtTop\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideSpellingErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hideGrammaticalErrors\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"activeWritingStyle\" type=\"CT_WritingStyle\" minOccurs=\"0\"\n        maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"proofState\" type=\"CT_Proof\" minOccurs=\"0\"/>\n      <xsd:element name=\"formsDesign\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"attachedTemplate\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkStyles\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneFormatFilter\" type=\"CT_StylePaneFilter\" minOccurs=\"0\"/>\n      <xsd:element name=\"stylePaneSortMethod\" type=\"CT_StyleSort\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentType\" type=\"CT_DocType\" minOccurs=\"0\"/>\n      <xsd:element name=\"mailMerge\" type=\"CT_MailMerge\" minOccurs=\"0\"/>\n      <xsd:element name=\"revisionView\" type=\"CT_TrackChangesView\" minOccurs=\"0\"/>\n      <xsd:element name=\"trackRevisions\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackMoves\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotTrackFormatting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"documentProtection\" type=\"CT_DocProtect\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoFormatOverride\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockTheme\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLockQFSet\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTabStop\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoHyphenation\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"consecutiveHyphenLimit\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"hyphenationZone\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotHyphenateCaps\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"showEnvelope\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"summaryLength\" type=\"CT_DecimalNumberOrPrecent\" minOccurs=\"0\"/>\n      <xsd:element name=\"clickAndTypeStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"defaultTableStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"evenAndOddHeaders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldRevPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrinting\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bookFoldPrintingSheets\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalSpacing\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayHorizontalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"displayVerticalDrawingGridEvery\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseMarginsForDrawingGridOrigin\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridHorizontalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"drawingGridVerticalOrigin\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotShadeFormData\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noPunctuationKerning\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"characterSpacingControl\" type=\"CT_CharacterSpacing\" minOccurs=\"0\"/>\n      <xsd:element name=\"printTwoOnOne\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"strictFirstAndLastChars\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksAfter\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"noLineBreaksBefore\" type=\"CT_Kinsoku\" minOccurs=\"0\"/>\n      <xsd:element name=\"savePreviewPicture\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotValidateAgainstSchema\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"ignoreMixedContent\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysShowPlaceholderText\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotDemarcateInvalidXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveXmlDataOnly\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"useXSLTWhenSaving\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveThroughXslt\" type=\"CT_SaveThroughXslt\" minOccurs=\"0\"/>\n      <xsd:element name=\"showXMLTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"alwaysMergeEmptyNamespace\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"updateFields\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hdrShapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"footnotePr\" type=\"CT_FtnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"endnotePr\" type=\"CT_EdnDocProps\" minOccurs=\"0\"/>\n      <xsd:element name=\"compat\" type=\"CT_Compat\" minOccurs=\"0\"/>\n      <xsd:element name=\"docVars\" type=\"CT_DocVars\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsids\" type=\"CT_DocRsids\" minOccurs=\"0\"/>\n      <xsd:element ref=\"m:mathPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"attachedSchema\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"themeFontLang\" type=\"CT_Language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"clrSchemeMapping\" type=\"CT_ColorSchemeMapping\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotIncludeSubdocsInStats\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotAutoCompressPictures\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"forceUpgrade\" type=\"CT_Empty\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"captions\" type=\"CT_Captions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"readModeInkLockDown\" type=\"CT_ReadingModeInkLockDown\" minOccurs=\"0\"/>\n      <xsd:element name=\"smartTagType\" type=\"CT_SmartTagType\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element ref=\"sl:schemaLibrary\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"shapeDefaults\" type=\"CT_ShapeDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotEmbedSmartTags\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"decimalSymbol\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"listSeparator\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StyleSort\">\n    <xsd:attribute name=\"val\" type=\"ST_StyleSort\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_StylePaneFilter\">\n    <xsd:attribute name=\"allStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"customStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"latentStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"stylesInUse\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"headingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"numberingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"tableStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnRuns\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnParagraphs\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnNumbering\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"directFormattingOnTables\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"clearFormatting\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"top3HeadingStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"visibleStyles\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"alternateStyleNames\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"val\" type=\"ST_ShortHexNumber\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleSort\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"name\"/>\n      <xsd:enumeration value=\"priority\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"font\"/>\n      <xsd:enumeration value=\"basedOn\"/>\n      <xsd:enumeration value=\"type\"/>\n      <xsd:enumeration value=\"0000\"/>\n      <xsd:enumeration value=\"0001\"/>\n      <xsd:enumeration value=\"0002\"/>\n      <xsd:enumeration value=\"0003\"/>\n      <xsd:enumeration value=\"0004\"/>\n      <xsd:enumeration value=\"0005\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_WebSettings\">\n    <xsd:sequence>\n      <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\"/>\n      <xsd:element name=\"divs\" type=\"CT_Divs\" minOccurs=\"0\"/>\n      <xsd:element name=\"encoding\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"optimizeForBrowser\" type=\"CT_OptimizeForBrowser\" minOccurs=\"0\"/>\n      <xsd:element name=\"relyOnVML\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"allowPNG\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotRelyOnCSS\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotSaveAsSingleFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotOrganizeInFolder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"doNotUseLongFileNames\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"pixelsPerInch\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"targetScreenSz\" type=\"CT_TargetScreenSz\" minOccurs=\"0\"/>\n      <xsd:element name=\"saveSmartTagsAsXml\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameScrollbar\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"on\"/>\n      <xsd:enumeration value=\"off\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameScrollbar\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameScrollbar\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_OptimizeForBrowser\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_OnOff\">\n        <xsd:attribute name=\"target\" type=\"s:ST_String\" use=\"optional\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frame\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"longDesc\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"sourceFileName\" type=\"CT_Rel\" minOccurs=\"0\"/>\n      <xsd:element name=\"marW\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"marH\" type=\"CT_PixelsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"scrollbar\" type=\"CT_FrameScrollbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"noResizeAllowed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"linkedToFile\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FrameLayout\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"rows\"/>\n      <xsd:enumeration value=\"cols\"/>\n      <xsd:enumeration value=\"none\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FrameLayout\">\n    <xsd:attribute name=\"val\" type=\"ST_FrameLayout\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FramesetSplitbar\">\n    <xsd:sequence>\n      <xsd:element name=\"w\" type=\"CT_TwipsMeasure\" minOccurs=\"0\"/>\n      <xsd:element name=\"color\" type=\"CT_Color\" minOccurs=\"0\"/>\n      <xsd:element name=\"noBorder\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"flatBorders\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Frameset\">\n    <xsd:sequence>\n      <xsd:element name=\"sz\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"framesetSplitbar\" type=\"CT_FramesetSplitbar\" minOccurs=\"0\"/>\n      <xsd:element name=\"frameLayout\" type=\"CT_FrameLayout\" minOccurs=\"0\"/>\n      <xsd:element name=\"title\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xsd:element name=\"frameset\" type=\"CT_Frameset\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        <xsd:element name=\"frame\" type=\"CT_Frame\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      </xsd:choice>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumPicBullet\">\n    <xsd:choice>\n      <xsd:element name=\"pict\" type=\"CT_Picture\"/>\n      <xsd:element name=\"drawing\" type=\"CT_Drawing\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"numPicBulletId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_LevelSuffix\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"tab\"/>\n      <xsd:enumeration value=\"space\"/>\n      <xsd:enumeration value=\"nothing\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_LevelSuffix\">\n    <xsd:attribute name=\"val\" type=\"ST_LevelSuffix\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LevelText\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"null\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LvlLegacy\">\n    <xsd:attribute name=\"legacy\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"legacySpace\" type=\"s:ST_TwipsMeasure\" use=\"optional\"/>\n    <xsd:attribute name=\"legacyIndent\" type=\"ST_SignedTwipsMeasure\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Lvl\">\n    <xsd:sequence>\n      <xsd:element name=\"start\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"numFmt\" type=\"CT_NumFmt\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlRestart\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pStyle\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"isLgl\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"suff\" type=\"CT_LevelSuffix\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlText\" type=\"CT_LevelText\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlPicBulletId\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"legacy\" type=\"CT_LvlLegacy\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvlJc\" type=\"CT_Jc\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n    <xsd:attribute name=\"tplc\" type=\"ST_LongHexNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"tentative\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_MultiLevelType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"singleLevel\"/>\n      <xsd:enumeration value=\"multilevel\"/>\n      <xsd:enumeration value=\"hybridMultilevel\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_MultiLevelType\">\n    <xsd:attribute name=\"val\" type=\"ST_MultiLevelType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AbstractNum\">\n    <xsd:sequence>\n      <xsd:element name=\"nsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"multiLevelType\" type=\"CT_MultiLevelType\" minOccurs=\"0\"/>\n      <xsd:element name=\"tmpl\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"styleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"numStyleLink\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"abstractNumId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_NumLvl\">\n    <xsd:sequence>\n      <xsd:element name=\"startOverride\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"lvl\" type=\"CT_Lvl\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"ilvl\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Num\">\n    <xsd:sequence>\n      <xsd:element name=\"abstractNumId\" type=\"CT_DecimalNumber\" minOccurs=\"1\"/>\n      <xsd:element name=\"lvlOverride\" type=\"CT_NumLvl\" minOccurs=\"0\" maxOccurs=\"9\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"numId\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Numbering\">\n    <xsd:sequence>\n      <xsd:element name=\"numPicBullet\" type=\"CT_NumPicBullet\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"abstractNum\" type=\"CT_AbstractNum\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"num\" type=\"CT_Num\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"numIdMacAtCleanup\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_TblStyleOverrideType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"wholeTable\"/>\n      <xsd:enumeration value=\"firstRow\"/>\n      <xsd:enumeration value=\"lastRow\"/>\n      <xsd:enumeration value=\"firstCol\"/>\n      <xsd:enumeration value=\"lastCol\"/>\n      <xsd:enumeration value=\"band1Vert\"/>\n      <xsd:enumeration value=\"band2Vert\"/>\n      <xsd:enumeration value=\"band1Horz\"/>\n      <xsd:enumeration value=\"band2Horz\"/>\n      <xsd:enumeration value=\"neCell\"/>\n      <xsd:enumeration value=\"nwCell\"/>\n      <xsd:enumeration value=\"seCell\"/>\n      <xsd:enumeration value=\"swCell\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_TblStylePr\">\n    <xsd:sequence>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_TblStyleOverrideType\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_StyleType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"paragraph\"/>\n      <xsd:enumeration value=\"character\"/>\n      <xsd:enumeration value=\"table\"/>\n      <xsd:enumeration value=\"numbering\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Style\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"aliases\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"basedOn\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"next\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"link\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"autoRedefine\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"hidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"uiPriority\" type=\"CT_DecimalNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"semiHidden\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"unhideWhenUsed\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"qFormat\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"locked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personal\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalCompose\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"personalReply\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"rsid\" type=\"CT_LongHexNumber\" minOccurs=\"0\"/>\n      <xsd:element name=\"pPr\" type=\"CT_PPrGeneral\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"rPr\" type=\"CT_RPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblPr\" type=\"CT_TblPrBase\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"trPr\" type=\"CT_TrPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tcPr\" type=\"CT_TcPr\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"tblStylePr\" type=\"CT_TblStylePr\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"type\" type=\"ST_StyleType\" use=\"optional\"/>\n    <xsd:attribute name=\"styleId\" type=\"s:ST_String\" use=\"optional\"/>\n    <xsd:attribute name=\"default\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"customStyle\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LsdException\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"locked\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"uiPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"semiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"unhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"qFormat\" type=\"s:ST_OnOff\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_LatentStyles\">\n    <xsd:sequence>\n      <xsd:element name=\"lsdException\" type=\"CT_LsdException\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"defLockedState\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUIPriority\" type=\"ST_DecimalNumber\"/>\n    <xsd:attribute name=\"defSemiHidden\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defUnhideWhenUsed\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"defQFormat\" type=\"s:ST_OnOff\"/>\n    <xsd:attribute name=\"count\" type=\"ST_DecimalNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Styles\">\n    <xsd:sequence>\n      <xsd:element name=\"docDefaults\" type=\"CT_DocDefaults\" minOccurs=\"0\"/>\n      <xsd:element name=\"latentStyles\" type=\"CT_LatentStyles\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_Style\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Panose\">\n    <xsd:attribute name=\"val\" type=\"s:ST_Panose\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_FontFamily\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"decorative\"/>\n      <xsd:enumeration value=\"modern\"/>\n      <xsd:enumeration value=\"roman\"/>\n      <xsd:enumeration value=\"script\"/>\n      <xsd:enumeration value=\"swiss\"/>\n      <xsd:enumeration value=\"auto\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_FontFamily\">\n    <xsd:attribute name=\"val\" type=\"ST_FontFamily\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_Pitch\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"fixed\"/>\n      <xsd:enumeration value=\"variable\"/>\n      <xsd:enumeration value=\"default\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Pitch\">\n    <xsd:attribute name=\"val\" type=\"ST_Pitch\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontSig\">\n    <xsd:attribute name=\"usb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb2\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"usb3\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb0\" use=\"required\" type=\"ST_LongHexNumber\"/>\n    <xsd:attribute name=\"csb1\" use=\"required\" type=\"ST_LongHexNumber\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontRel\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_Rel\">\n        <xsd:attribute name=\"fontKey\" type=\"s:ST_Guid\"/>\n        <xsd:attribute name=\"subsetted\" type=\"s:ST_OnOff\"/>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Font\">\n    <xsd:sequence>\n      <xsd:element name=\"altName\" type=\"CT_String\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"panose1\" type=\"CT_Panose\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"charset\" type=\"CT_Charset\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"family\" type=\"CT_FontFamily\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"notTrueType\" type=\"CT_OnOff\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"pitch\" type=\"CT_Pitch\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"sig\" type=\"CT_FontSig\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedRegular\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBold\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xsd:element name=\"embedBoldItalic\" type=\"CT_FontRel\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_FontsList\">\n    <xsd:sequence>\n      <xsd:element name=\"font\" type=\"CT_Font\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DivBdr\">\n    <xsd:sequence>\n      <xsd:element name=\"top\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"left\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"bottom\" type=\"CT_Border\" minOccurs=\"0\"/>\n      <xsd:element name=\"right\" type=\"CT_Border\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Div\">\n    <xsd:sequence>\n      <xsd:element name=\"blockQuote\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"bodyDiv\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n      <xsd:element name=\"marLeft\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marRight\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marTop\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"marBottom\" type=\"CT_SignedTwipsMeasure\"/>\n      <xsd:element name=\"divBdr\" type=\"CT_DivBdr\" minOccurs=\"0\"/>\n      <xsd:element name=\"divsChild\" type=\"CT_Divs\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"ST_DecimalNumber\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Divs\">\n    <xsd:sequence minOccurs=\"1\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"div\" type=\"CT_Div\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_TxbxContent\">\n    <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n  </xsd:complexType>\n  <xsd:element name=\"txbxContent\" type=\"CT_TxbxContent\"/>\n  <xsd:group name=\"EG_MathContent\">\n    <xsd:choice>\n      <xsd:element ref=\"m:oMathPara\"/>\n      <xsd:element ref=\"m:oMath\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelChunkElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_ContentBlockContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_BlockLevelElts\">\n    <xsd:choice>\n      <xsd:group ref=\"EG_BlockLevelChunkElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"altChunk\" type=\"CT_AltChunk\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:group name=\"EG_RunLevelElts\">\n    <xsd:choice>\n      <xsd:element name=\"proofErr\" minOccurs=\"0\" type=\"CT_ProofErr\"/>\n      <xsd:element name=\"permStart\" minOccurs=\"0\" type=\"CT_PermStart\"/>\n      <xsd:element name=\"permEnd\" minOccurs=\"0\" type=\"CT_Perm\"/>\n      <xsd:group ref=\"EG_RangeMarkupElements\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"ins\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"del\" type=\"CT_RunTrackChange\" minOccurs=\"0\"/>\n      <xsd:element name=\"moveFrom\" type=\"CT_RunTrackChange\"/>\n      <xsd:element name=\"moveTo\" type=\"CT_RunTrackChange\"/>\n      <xsd:group ref=\"EG_MathContent\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:group>\n  <xsd:complexType name=\"CT_Body\">\n    <xsd:sequence>\n      <xsd:group ref=\"EG_BlockLevelElts\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"sectPr\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_SectPr\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_ShapeDefaults\">\n    <xsd:choice maxOccurs=\"unbounded\">\n      <xsd:any processContents=\"lax\" namespace=\"urn:schemas-microsoft-com:office:office\"\n        minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Comments\">\n    <xsd:sequence>\n      <xsd:element name=\"comment\" type=\"CT_Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"comments\" type=\"CT_Comments\"/>\n  <xsd:complexType name=\"CT_Footnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"footnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"footnotes\" type=\"CT_Footnotes\"/>\n  <xsd:complexType name=\"CT_Endnotes\">\n    <xsd:sequence maxOccurs=\"unbounded\">\n      <xsd:element name=\"endnote\" type=\"CT_FtnEdn\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:element name=\"endnotes\" type=\"CT_Endnotes\"/>\n  <xsd:element name=\"hdr\" type=\"CT_HdrFtr\"/>\n  <xsd:element name=\"ftr\" type=\"CT_HdrFtr\"/>\n  <xsd:complexType name=\"CT_SmartTagType\">\n    <xsd:attribute name=\"namespaceuri\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"name\" type=\"s:ST_String\"/>\n    <xsd:attribute name=\"url\" type=\"s:ST_String\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_ThemeColor\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"dark1\"/>\n      <xsd:enumeration value=\"light1\"/>\n      <xsd:enumeration value=\"dark2\"/>\n      <xsd:enumeration value=\"light2\"/>\n      <xsd:enumeration value=\"accent1\"/>\n      <xsd:enumeration value=\"accent2\"/>\n      <xsd:enumeration value=\"accent3\"/>\n      <xsd:enumeration value=\"accent4\"/>\n      <xsd:enumeration value=\"accent5\"/>\n      <xsd:enumeration value=\"accent6\"/>\n      <xsd:enumeration value=\"hyperlink\"/>\n      <xsd:enumeration value=\"followedHyperlink\"/>\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"background1\"/>\n      <xsd:enumeration value=\"text1\"/>\n      <xsd:enumeration value=\"background2\"/>\n      <xsd:enumeration value=\"text2\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:simpleType name=\"ST_DocPartBehavior\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"content\"/>\n      <xsd:enumeration value=\"p\"/>\n      <xsd:enumeration value=\"pg\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartBehavior\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartBehavior\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartBehaviors\">\n    <xsd:choice>\n      <xsd:element name=\"behavior\" type=\"CT_DocPartBehavior\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartType\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"none\"/>\n      <xsd:enumeration value=\"normal\"/>\n      <xsd:enumeration value=\"autoExp\"/>\n      <xsd:enumeration value=\"toolbar\"/>\n      <xsd:enumeration value=\"speller\"/>\n      <xsd:enumeration value=\"formFld\"/>\n      <xsd:enumeration value=\"bbPlcHdr\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartType\">\n    <xsd:attribute name=\"val\" use=\"required\" type=\"ST_DocPartType\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartTypes\">\n    <xsd:choice>\n      <xsd:element name=\"type\" type=\"CT_DocPartType\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n    <xsd:attribute name=\"all\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:simpleType name=\"ST_DocPartGallery\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"placeholder\"/>\n      <xsd:enumeration value=\"any\"/>\n      <xsd:enumeration value=\"default\"/>\n      <xsd:enumeration value=\"docParts\"/>\n      <xsd:enumeration value=\"coverPg\"/>\n      <xsd:enumeration value=\"eq\"/>\n      <xsd:enumeration value=\"ftrs\"/>\n      <xsd:enumeration value=\"hdrs\"/>\n      <xsd:enumeration value=\"pgNum\"/>\n      <xsd:enumeration value=\"tbls\"/>\n      <xsd:enumeration value=\"watermarks\"/>\n      <xsd:enumeration value=\"autoTxt\"/>\n      <xsd:enumeration value=\"txtBox\"/>\n      <xsd:enumeration value=\"pgNumT\"/>\n      <xsd:enumeration value=\"pgNumB\"/>\n      <xsd:enumeration value=\"pgNumMargins\"/>\n      <xsd:enumeration value=\"tblOfContents\"/>\n      <xsd:enumeration value=\"bib\"/>\n      <xsd:enumeration value=\"custQuickParts\"/>\n      <xsd:enumeration value=\"custCoverPg\"/>\n      <xsd:enumeration value=\"custEq\"/>\n      <xsd:enumeration value=\"custFtrs\"/>\n      <xsd:enumeration value=\"custHdrs\"/>\n      <xsd:enumeration value=\"custPgNum\"/>\n      <xsd:enumeration value=\"custTbls\"/>\n      <xsd:enumeration value=\"custWatermarks\"/>\n      <xsd:enumeration value=\"custAutoTxt\"/>\n      <xsd:enumeration value=\"custTxtBox\"/>\n      <xsd:enumeration value=\"custPgNumT\"/>\n      <xsd:enumeration value=\"custPgNumB\"/>\n      <xsd:enumeration value=\"custPgNumMargins\"/>\n      <xsd:enumeration value=\"custTblOfContents\"/>\n      <xsd:enumeration value=\"custBib\"/>\n      <xsd:enumeration value=\"custom1\"/>\n      <xsd:enumeration value=\"custom2\"/>\n      <xsd:enumeration value=\"custom3\"/>\n      <xsd:enumeration value=\"custom4\"/>\n      <xsd:enumeration value=\"custom5\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_DocPartGallery\">\n    <xsd:attribute name=\"val\" type=\"ST_DocPartGallery\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartCategory\">\n    <xsd:sequence>\n      <xsd:element name=\"name\" type=\"CT_String\" minOccurs=\"1\" maxOccurs=\"1\"/>\n      <xsd:element name=\"gallery\" type=\"CT_DocPartGallery\" minOccurs=\"1\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartName\">\n    <xsd:attribute name=\"val\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"decorated\" type=\"s:ST_OnOff\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPartPr\">\n    <xsd:all>\n      <xsd:element name=\"name\" type=\"CT_DocPartName\" minOccurs=\"1\"/>\n      <xsd:element name=\"style\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"category\" type=\"CT_DocPartCategory\" minOccurs=\"0\"/>\n      <xsd:element name=\"types\" type=\"CT_DocPartTypes\" minOccurs=\"0\"/>\n      <xsd:element name=\"behaviors\" type=\"CT_DocPartBehaviors\" minOccurs=\"0\"/>\n      <xsd:element name=\"description\" type=\"CT_String\" minOccurs=\"0\"/>\n      <xsd:element name=\"guid\" type=\"CT_Guid\" minOccurs=\"0\"/>\n    </xsd:all>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocPart\">\n    <xsd:sequence>\n      <xsd:element name=\"docPartPr\" type=\"CT_DocPartPr\" minOccurs=\"0\"/>\n      <xsd:element name=\"docPartBody\" type=\"CT_Body\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocParts\">\n    <xsd:choice>\n      <xsd:element name=\"docPart\" type=\"CT_DocPart\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:choice>\n  </xsd:complexType>\n  <xsd:element name=\"settings\" type=\"CT_Settings\"/>\n  <xsd:element name=\"webSettings\" type=\"CT_WebSettings\"/>\n  <xsd:element name=\"fonts\" type=\"CT_FontsList\"/>\n  <xsd:element name=\"numbering\" type=\"CT_Numbering\"/>\n  <xsd:element name=\"styles\" type=\"CT_Styles\"/>\n  <xsd:simpleType name=\"ST_CaptionPos\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"above\"/>\n      <xsd:enumeration value=\"below\"/>\n      <xsd:enumeration value=\"left\"/>\n      <xsd:enumeration value=\"right\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n  <xsd:complexType name=\"CT_Caption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"pos\" type=\"ST_CaptionPos\" use=\"optional\"/>\n    <xsd:attribute name=\"chapNum\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"heading\" type=\"ST_DecimalNumber\" use=\"optional\"/>\n    <xsd:attribute name=\"noLabel\" type=\"s:ST_OnOff\" use=\"optional\"/>\n    <xsd:attribute name=\"numFmt\" type=\"ST_NumberFormat\" use=\"optional\"/>\n    <xsd:attribute name=\"sep\" type=\"ST_ChapterSep\" use=\"optional\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaption\">\n    <xsd:attribute name=\"name\" type=\"s:ST_String\" use=\"required\"/>\n    <xsd:attribute name=\"caption\" type=\"s:ST_String\" use=\"required\"/>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_AutoCaptions\">\n    <xsd:sequence>\n      <xsd:element name=\"autoCaption\" type=\"CT_AutoCaption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Captions\">\n    <xsd:sequence>\n      <xsd:element name=\"caption\" type=\"CT_Caption\" minOccurs=\"1\" maxOccurs=\"unbounded\"/>\n      <xsd:element name=\"autoCaptions\" type=\"CT_AutoCaptions\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_DocumentBase\">\n    <xsd:sequence>\n      <xsd:element name=\"background\" type=\"CT_Background\" minOccurs=\"0\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_Document\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"body\" type=\"CT_Body\" minOccurs=\"0\" maxOccurs=\"1\"/>\n        </xsd:sequence>\n        <xsd:attribute name=\"conformance\" type=\"s:ST_ConformanceClass\"/>\n        <xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:complexType name=\"CT_GlossaryDocument\">\n    <xsd:complexContent>\n      <xsd:extension base=\"CT_DocumentBase\">\n        <xsd:sequence>\n          <xsd:element name=\"docParts\" type=\"CT_DocParts\" minOccurs=\"0\"/>\n        </xsd:sequence>\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n  <xsd:element name=\"document\" type=\"CT_Document\"/>\n  <xsd:element name=\"glossaryDocument\" type=\"CT_GlossaryDocument\"/>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd",
    "content": "<?xml version='1.0'?>\n<xs:schema targetNamespace=\"http://www.w3.org/XML/1998/namespace\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xml:lang=\"en\">\n\n <xs:annotation>\n  <xs:documentation>\n   See http://www.w3.org/XML/1998/namespace.html and\n   http://www.w3.org/TR/REC-xml for information about this namespace.\n\n    This schema document describes the XML namespace, in a form\n    suitable for import by other schema documents.  \n\n    Note that local names in this namespace are intended to be defined\n    only by the World Wide Web Consortium or its subgroups.  The\n    following names are currently defined in this namespace and should\n    not be used with conflicting semantics by any Working Group,\n    specification, or document instance:\n\n    base (as an attribute name): denotes an attribute whose value\n         provides a URI to be used as the base for interpreting any\n         relative URIs in the scope of the element on which it\n         appears; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML Base specification.\n\n    lang (as an attribute name): denotes an attribute whose value\n         is a language code for the natural language of the content of\n         any element; its value is inherited.  This name is reserved\n         by virtue of its definition in the XML specification.\n  \n    space (as an attribute name): denotes an attribute whose\n         value is a keyword indicating what whitespace processing\n         discipline is intended for the content of the element; its\n         value is inherited.  This name is reserved by virtue of its\n         definition in the XML specification.\n\n    Father (in any context at all): denotes Jon Bosak, the chair of \n         the original XML Working Group.  This name is reserved by \n         the following decision of the W3C XML Plenary and \n         XML Coordination groups:\n\n             In appreciation for his vision, leadership and dedication\n             the W3C XML Plenary on this 10th day of February, 2000\n             reserves for Jon Bosak in perpetuity the XML name\n             xml:Father\n  </xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>This schema defines attributes and an attribute group\n        suitable for use by\n        schemas wishing to allow xml:base, xml:lang or xml:space attributes\n        on elements they define.\n\n        To enable this, such a schema must import this schema\n        for the XML namespace, e.g. as follows:\n        &lt;schema . . .>\n         . . .\n         &lt;import namespace=\"http://www.w3.org/XML/1998/namespace\"\n                    schemaLocation=\"http://www.w3.org/2001/03/xml.xsd\"/>\n\n        Subsequently, qualified reference to any of the attributes\n        or the group defined below will have the desired effect, e.g.\n\n        &lt;type . . .>\n         . . .\n         &lt;attributeGroup ref=\"xml:specialAttrs\"/>\n \n         will define a type which will schema-validate an instance\n         element with any of those attributes</xs:documentation>\n </xs:annotation>\n\n <xs:annotation>\n  <xs:documentation>In keeping with the XML Schema WG's standard versioning\n   policy, this schema document will persist at\n   http://www.w3.org/2001/03/xml.xsd.\n   At the date of issue it can also be found at\n   http://www.w3.org/2001/xml.xsd.\n   The schema document at that URI may however change in the future,\n   in order to remain compatible with the latest version of XML Schema\n   itself.  In other words, if the XML Schema namespace changes, the version\n   of this document at\n   http://www.w3.org/2001/xml.xsd will change\n   accordingly; the version at\n   http://www.w3.org/2001/03/xml.xsd will not change.\n  </xs:documentation>\n </xs:annotation>\n\n <xs:attribute name=\"lang\" type=\"xs:language\">\n  <xs:annotation>\n   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter\n         codes as the enumerated possible values . . .</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attribute name=\"space\" default=\"preserve\">\n  <xs:simpleType>\n   <xs:restriction base=\"xs:NCName\">\n    <xs:enumeration value=\"default\"/>\n    <xs:enumeration value=\"preserve\"/>\n   </xs:restriction>\n  </xs:simpleType>\n </xs:attribute>\n\n <xs:attribute name=\"base\" type=\"xs:anyURI\">\n  <xs:annotation>\n   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for\n                     information about this attribute.</xs:documentation>\n  </xs:annotation>\n </xs:attribute>\n\n <xs:attributeGroup name=\"specialAttrs\">\n  <xs:attribute ref=\"xml:base\"/>\n  <xs:attribute ref=\"xml:lang\"/>\n  <xs:attribute ref=\"xml:space\"/>\n </xs:attributeGroup>\n\n</xs:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xs:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/content-types\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xs:element name=\"Types\" type=\"CT_Types\"/>\n  <xs:element name=\"Default\" type=\"CT_Default\"/>\n  <xs:element name=\"Override\" type=\"CT_Override\"/>\n\n  <xs:complexType name=\"CT_Types\">\n    <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xs:element ref=\"Default\"/>\n      <xs:element ref=\"Override\"/>\n    </xs:choice>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Default\">\n    <xs:attribute name=\"Extension\" type=\"ST_Extension\" use=\"required\"/>\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Override\">\n    <xs:attribute name=\"ContentType\" type=\"ST_ContentType\" use=\"required\"/>\n    <xs:attribute name=\"PartName\" type=\"xs:anyURI\" use=\"required\"/>\n  </xs:complexType>\n\n  <xs:simpleType name=\"ST_ContentType\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))/((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))((\\s+)*;(\\s+)*(((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+))=((([\\p{IsBasicLatin}-[\\p{Cc}&#127;\\(\\)&lt;&gt;@,;:\\\\&quot;/\\[\\]\\?=\\{\\}\\s\\t]])+)|(&quot;(([\\p{IsLatin-1Supplement}\\p{IsBasicLatin}-[\\p{Cc}&#127;&quot;\\n\\r]]|(\\s+))|(\\\\[\\p{IsBasicLatin}]))*&quot;))))*)\"\n      />\n    </xs:restriction>\n  </xs:simpleType>\n\n  <xs:simpleType name=\"ST_Extension\">\n    <xs:restriction base=\"xs:string\">\n      <xs:pattern\n        value=\"([!$&amp;'\\(\\)\\*\\+,:=]|(%[0-9a-fA-F][0-9a-fA-F])|[:@]|[a-zA-Z0-9\\-_~])+\"/>\n    </xs:restriction>\n  </xs:simpleType>\n</xs:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema targetNamespace=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\"\n  xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:dcterms=\"http://purl.org/dc/terms/\" elementFormDefault=\"qualified\" blockDefault=\"#all\">\n\n  <xs:import namespace=\"http://purl.org/dc/elements/1.1/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dc.xsd\"/>\n  <xs:import namespace=\"http://purl.org/dc/terms/\"\n    schemaLocation=\"http://dublincore.org/schemas/xmls/qdc/2003/04/02/dcterms.xsd\"/>\n  <xs:import id=\"xml\" namespace=\"http://www.w3.org/XML/1998/namespace\"/>\n\n  <xs:element name=\"coreProperties\" type=\"CT_CoreProperties\"/>\n\n  <xs:complexType name=\"CT_CoreProperties\">\n    <xs:all>\n      <xs:element name=\"category\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"contentStatus\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dcterms:created\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:creator\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:description\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:identifier\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"keywords\" minOccurs=\"0\" maxOccurs=\"1\" type=\"CT_Keywords\"/>\n      <xs:element ref=\"dc:language\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"lastModifiedBy\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element name=\"lastPrinted\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:dateTime\"/>\n      <xs:element ref=\"dcterms:modified\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"revision\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n      <xs:element ref=\"dc:subject\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element ref=\"dc:title\" minOccurs=\"0\" maxOccurs=\"1\"/>\n      <xs:element name=\"version\" minOccurs=\"0\" maxOccurs=\"1\" type=\"xs:string\"/>\n    </xs:all>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keywords\" mixed=\"true\">\n    <xs:sequence>\n      <xs:element name=\"value\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_Keyword\"/>\n    </xs:sequence>\n    <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n  </xs:complexType>\n\n  <xs:complexType name=\"CT_Keyword\">\n    <xs:simpleContent>\n      <xs:extension base=\"xs:string\">\n        <xs:attribute ref=\"xml:lang\" use=\"optional\"/>\n      </xs:extension>\n    </xs:simpleContent>\n  </xs:complexType>\n\n</xs:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/digital-signature\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"SignatureTime\" type=\"CT_SignatureTime\"/>\n  <xsd:element name=\"RelationshipReference\" type=\"CT_RelationshipReference\"/>\n  <xsd:element name=\"RelationshipsGroupReference\" type=\"CT_RelationshipsGroupReference\"/>\n\n  <xsd:complexType name=\"CT_SignatureTime\">\n    <xsd:sequence>\n      <xsd:element name=\"Format\" type=\"ST_Format\"/>\n      <xsd:element name=\"Value\" type=\"ST_Value\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceId\" type=\"xsd:string\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_RelationshipsGroupReference\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"SourceType\" type=\"xsd:anyURI\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_Format\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(YYYY)|(YYYY-MM)|(YYYY-MM-DD)|(YYYY-MM-DDThh:mmTZD)|(YYYY-MM-DDThh:mm:ssTZD)|(YYYY-MM-DDThh:mm:ss.sTZD)\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n\n  <xsd:simpleType name=\"ST_Value\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:pattern\n        value=\"(([0-9][0-9][0-9][0-9]))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1))))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))|(([0-9][0-9][0-9][0-9])-((0[1-9])|(1(0|1|2)))-((0[1-9])|(1[0-9])|(2[0-9])|(3(0|1)))T((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])):(((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9]))\\.[0-9])(((\\+|-)((0[0-9])|(1[0-9])|(2(0|1|2|3))):((0[0-9])|(1[0-9])|(2[0-9])|(3[0-9])|(4[0-9])|(5[0-9])))|Z))\"\n      />\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<xsd:schema xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  targetNamespace=\"http://schemas.openxmlformats.org/package/2006/relationships\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" blockDefault=\"#all\">\n\n  <xsd:element name=\"Relationships\" type=\"CT_Relationships\"/>\n  <xsd:element name=\"Relationship\" type=\"CT_Relationship\"/>\n\n  <xsd:complexType name=\"CT_Relationships\">\n    <xsd:sequence>\n      <xsd:element ref=\"Relationship\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n    </xsd:sequence>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"CT_Relationship\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"TargetMode\" type=\"ST_TargetMode\" use=\"optional\"/>\n        <xsd:attribute name=\"Target\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Type\" type=\"xsd:anyURI\" use=\"required\"/>\n        <xsd:attribute name=\"Id\" type=\"xsd:ID\" use=\"required\"/>\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:simpleType name=\"ST_TargetMode\">\n    <xsd:restriction base=\"xsd:string\">\n      <xsd:enumeration value=\"External\"/>\n      <xsd:enumeration value=\"Internal\"/>\n    </xsd:restriction>\n  </xsd:simpleType>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/mce/mc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xsd:schema xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\tattributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\"\n\ttargetNamespace=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--\n    This XSD is a modified version of the one found at:\n    https://github.com/plutext/docx4j/blob/master/xsd/mce/markup-compatibility-2006-MINIMAL.xsd\n\n    This XSD has 2 objectives:\n\n        1. round tripping @mc:Ignorable\n\n\t\t\t<w:document\n\t\t\t            xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t            xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t\t\t            mc:Ignorable=\"w14 w15 wp14\">\n\n        2. enabling AlternateContent to be manipulated in certain elements\n           (in the unusual case where the content model is xsd:any, it doesn't have to be explicitly added)\n\n\t\tSee further ECMA-376, 4th Edition, Office Open XML File Formats\n\t\tPart 3 : Markup Compatibility and Extensibility\n   -->\n\n  <!--  Objective 1 -->\n  <xsd:attribute name=\"Ignorable\" type=\"xsd:string\" />\n\n  <!--  Objective 2 -->\n\t<xsd:attribute name=\"MustUnderstand\" type=\"xsd:string\"  />\n\t<xsd:attribute name=\"ProcessContent\" type=\"xsd:string\"  />\n\n<!-- An AlternateContent element shall contain one or more Choice child elements, optionally followed by a\nFallback child element. If present, there shall be only one Fallback element, and it shall follow all Choice\nelements. -->\n\t<xsd:element name=\"AlternateContent\">\n\t\t<xsd:complexType>\n\t\t\t<xsd:sequence>\n\t\t\t\t<xsd:element name=\"Choice\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute name=\"Requires\" type=\"xsd:string\" use=\"required\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t\t<xsd:element name=\"Fallback\" minOccurs=\"0\" maxOccurs=\"1\">\n\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t<xsd:any minOccurs=\"0\" maxOccurs=\"unbounded\"\n\t\t\t\t\t\t\t\tprocessContents=\"strict\">\n\t\t\t\t\t\t\t</xsd:any>\n\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t\t\t\t</xsd:complexType>\n\t\t\t\t</xsd:element>\n\t\t\t</xsd:sequence>\n\t\t\t<!-- AlternateContent elements might include the attributes Ignorable,\n\t\t\t\tMustUnderstand and ProcessContent described in this Part of ECMA-376. These\n\t\t\t\tattributes’ qualified names shall be prefixed when associated with an AlternateContent\n\t\t\t\telement. -->\n\t\t\t<xsd:attribute ref=\"mc:Ignorable\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:MustUnderstand\" use=\"optional\" />\n\t\t\t<xsd:attribute ref=\"mc:ProcessContent\" use=\"optional\" />\n\t\t</xsd:complexType>\n\t</xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns=\"http://schemas.microsoft.com/office/word/2010/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2010/wordml\">\n   <!-- <xsd:import id=\"rel\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" schemaLocation=\"orel.xsd\"/> -->\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <!-- <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartbasetypes.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/drawingml/2006/main\" schemaLocation=\"oartsplineproperties.xsd\"/> -->\n   <xsd:complexType name=\"CT_LongHexNumber\">\n     <xsd:attribute name=\"val\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_OnOff\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"true\"/>\n       <xsd:enumeration value=\"false\"/>\n       <xsd:enumeration value=\"0\"/>\n       <xsd:enumeration value=\"1\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_OnOff\">\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\"/>\n   </xsd:complexType>\n   <xsd:element name=\"docId\" type=\"CT_LongHexNumber\"/>\n   <xsd:element name=\"conflictMode\" type=\"CT_OnOff\"/>\n   <xsd:attributeGroup name=\"AG_Parids\">\n     <xsd:attribute name=\"paraId\" type=\"w:ST_LongHexNumber\"/>\n     <xsd:attribute name=\"textId\" type=\"w:ST_LongHexNumber\"/>\n   </xsd:attributeGroup>\n   <xsd:attribute name=\"anchorId\" type=\"w:ST_LongHexNumber\"/>\n   <xsd:attribute name=\"noSpellErr\" type=\"ST_OnOff\"/>\n   <xsd:element name=\"customXmlConflictInsRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictInsRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:element name=\"customXmlConflictDelRangeStart\" type=\"w:CT_TrackChange\"/>\n   <xsd:element name=\"customXmlConflictDelRangeEnd\" type=\"w:CT_Markup\"/>\n   <xsd:group name=\"EG_RunLevelConflicts\">\n     <xsd:sequence>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_RunTrackChange\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:group name=\"EG_Conflicts\">\n     <xsd:choice>\n       <xsd:element name=\"conflictIns\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n       <xsd:element name=\"conflictDel\" type=\"w:CT_TrackChange\" minOccurs=\"0\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Percentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_Percentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositiveFixedPercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PositivePercentage\">\n     <xsd:attribute name=\"val\" type=\"a:ST_PositivePercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_SchemeColorVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"bg1\"/>\n       <xsd:enumeration value=\"tx1\"/>\n       <xsd:enumeration value=\"bg2\"/>\n       <xsd:enumeration value=\"tx2\"/>\n       <xsd:enumeration value=\"accent1\"/>\n       <xsd:enumeration value=\"accent2\"/>\n       <xsd:enumeration value=\"accent3\"/>\n       <xsd:enumeration value=\"accent4\"/>\n       <xsd:enumeration value=\"accent5\"/>\n       <xsd:enumeration value=\"accent6\"/>\n       <xsd:enumeration value=\"hlink\"/>\n       <xsd:enumeration value=\"folHlink\"/>\n       <xsd:enumeration value=\"dk1\"/>\n       <xsd:enumeration value=\"lt1\"/>\n       <xsd:enumeration value=\"dk2\"/>\n       <xsd:enumeration value=\"lt2\"/>\n       <xsd:enumeration value=\"phClr\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_RectAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PathShadeType\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"shape\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"rect\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LineCap\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"rnd\"/>\n       <xsd:enumeration value=\"sq\"/>\n       <xsd:enumeration value=\"flat\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PresetLineDashVal\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"solid\"/>\n       <xsd:enumeration value=\"dot\"/>\n       <xsd:enumeration value=\"sysDot\"/>\n       <xsd:enumeration value=\"dash\"/>\n       <xsd:enumeration value=\"sysDash\"/>\n       <xsd:enumeration value=\"lgDash\"/>\n       <xsd:enumeration value=\"dashDot\"/>\n       <xsd:enumeration value=\"sysDashDot\"/>\n       <xsd:enumeration value=\"lgDashDot\"/>\n       <xsd:enumeration value=\"lgDashDotDot\"/>\n       <xsd:enumeration value=\"sysDashDotDot\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_PenAlignment\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"ctr\"/>\n       <xsd:enumeration value=\"in\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_CompoundLine\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"sng\"/>\n       <xsd:enumeration value=\"dbl\"/>\n       <xsd:enumeration value=\"thickThin\"/>\n       <xsd:enumeration value=\"thinThick\"/>\n       <xsd:enumeration value=\"tri\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_RelativeRect\">\n     <xsd:attribute name=\"l\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"t\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"r\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"b\" use=\"optional\" type=\"a:ST_Percentage\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorTransform\">\n     <xsd:choice>\n       <xsd:element name=\"tint\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"shade\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"alpha\" type=\"CT_PositiveFixedPercentage\"/>\n       <xsd:element name=\"hueMod\" type=\"CT_PositivePercentage\"/>\n       <xsd:element name=\"sat\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"satMod\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lum\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumOff\" type=\"CT_Percentage\"/>\n       <xsd:element name=\"lumMod\" type=\"CT_Percentage\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SRgbColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"s:ST_HexColorRGB\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SchemeColor\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorTransform\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"val\" type=\"ST_SchemeColorVal\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ColorChoice\">\n     <xsd:choice>\n       <xsd:element name=\"srgbClr\" type=\"CT_SRgbColor\"/>\n       <xsd:element name=\"schemeClr\" type=\"CT_SchemeColor\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_Color\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStop\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"pos\" type=\"a:ST_PositiveFixedPercentage\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientStopList\">\n     <xsd:sequence>\n       <xsd:element name=\"gs\" type=\"CT_GradientStop\" minOccurs=\"2\" maxOccurs=\"10\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_LinearShadeProperties\">\n     <xsd:attribute name=\"ang\" type=\"a:ST_PositiveFixedAngle\" use=\"optional\"/>\n     <xsd:attribute name=\"scaled\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PathShadeProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"fillToRect\" type=\"CT_RelativeRect\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"path\" type=\"ST_PathShadeType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_ShadeProperties\">\n     <xsd:choice>\n       <xsd:element name=\"lin\" type=\"CT_LinearShadeProperties\"/>\n       <xsd:element name=\"path\" type=\"CT_PathShadeProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_SolidColorFillProperties\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_GradientFillProperties\">\n     <xsd:sequence>\n       <xsd:element name=\"gsLst\" type=\"CT_GradientStopList\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_ShadeProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_FillProperties\">\n     <xsd:choice>\n       <xsd:element name=\"noFill\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"solidFill\" type=\"CT_SolidColorFillProperties\"/>\n       <xsd:element name=\"gradFill\" type=\"CT_GradientFillProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_PresetLineDashProperties\">\n     <xsd:attribute name=\"val\" type=\"ST_PresetLineDashVal\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineDashProperties\">\n     <xsd:choice>\n       <xsd:element name=\"prstDash\" type=\"CT_PresetLineDashProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:complexType name=\"CT_LineJoinMiterProperties\">\n     <xsd:attribute name=\"lim\" type=\"a:ST_PositivePercentage\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_LineJoinProperties\">\n     <xsd:choice>\n       <xsd:element name=\"round\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"bevel\" type=\"w:CT_Empty\"/>\n       <xsd:element name=\"miter\" type=\"CT_LineJoinMiterProperties\"/>\n     </xsd:choice>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_PresetCameraType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyObliqueTopLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueTop\"/>\n       <xsd:enumeration value=\"legacyObliqueTopRight\"/>\n       <xsd:enumeration value=\"legacyObliqueLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueFront\"/>\n       <xsd:enumeration value=\"legacyObliqueRight\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomLeft\"/>\n       <xsd:enumeration value=\"legacyObliqueBottom\"/>\n       <xsd:enumeration value=\"legacyObliqueBottomRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTop\"/>\n       <xsd:enumeration value=\"legacyPerspectiveTopRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveFront\"/>\n       <xsd:enumeration value=\"legacyPerspectiveRight\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomLeft\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottom\"/>\n       <xsd:enumeration value=\"legacyPerspectiveBottomRight\"/>\n       <xsd:enumeration value=\"orthographicFront\"/>\n       <xsd:enumeration value=\"isometricTopUp\"/>\n       <xsd:enumeration value=\"isometricTopDown\"/>\n       <xsd:enumeration value=\"isometricBottomUp\"/>\n       <xsd:enumeration value=\"isometricBottomDown\"/>\n       <xsd:enumeration value=\"isometricLeftUp\"/>\n       <xsd:enumeration value=\"isometricLeftDown\"/>\n       <xsd:enumeration value=\"isometricRightUp\"/>\n       <xsd:enumeration value=\"isometricRightDown\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis1Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis2Top\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis3Bottom\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Left\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Right\"/>\n       <xsd:enumeration value=\"isometricOffAxis4Bottom\"/>\n       <xsd:enumeration value=\"obliqueTopLeft\"/>\n       <xsd:enumeration value=\"obliqueTop\"/>\n       <xsd:enumeration value=\"obliqueTopRight\"/>\n       <xsd:enumeration value=\"obliqueLeft\"/>\n       <xsd:enumeration value=\"obliqueRight\"/>\n       <xsd:enumeration value=\"obliqueBottomLeft\"/>\n       <xsd:enumeration value=\"obliqueBottom\"/>\n       <xsd:enumeration value=\"obliqueBottomRight\"/>\n       <xsd:enumeration value=\"perspectiveFront\"/>\n       <xsd:enumeration value=\"perspectiveLeft\"/>\n       <xsd:enumeration value=\"perspectiveRight\"/>\n       <xsd:enumeration value=\"perspectiveAbove\"/>\n       <xsd:enumeration value=\"perspectiveBelow\"/>\n       <xsd:enumeration value=\"perspectiveAboveLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveAboveRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveContrastingRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeLeftFacing\"/>\n       <xsd:enumeration value=\"perspectiveHeroicExtremeRightFacing\"/>\n       <xsd:enumeration value=\"perspectiveRelaxed\"/>\n       <xsd:enumeration value=\"perspectiveRelaxedModerately\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Camera\">\n     <xsd:attribute name=\"prst\" use=\"required\" type=\"ST_PresetCameraType\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SphereCoords\">\n     <xsd:attribute name=\"lat\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"lon\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n     <xsd:attribute name=\"rev\" type=\"a:ST_PositiveFixedAngle\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_LightRigType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyFlat1\"/>\n       <xsd:enumeration value=\"legacyFlat2\"/>\n       <xsd:enumeration value=\"legacyFlat3\"/>\n       <xsd:enumeration value=\"legacyFlat4\"/>\n       <xsd:enumeration value=\"legacyNormal1\"/>\n       <xsd:enumeration value=\"legacyNormal2\"/>\n       <xsd:enumeration value=\"legacyNormal3\"/>\n       <xsd:enumeration value=\"legacyNormal4\"/>\n       <xsd:enumeration value=\"legacyHarsh1\"/>\n       <xsd:enumeration value=\"legacyHarsh2\"/>\n       <xsd:enumeration value=\"legacyHarsh3\"/>\n       <xsd:enumeration value=\"legacyHarsh4\"/>\n       <xsd:enumeration value=\"threePt\"/>\n       <xsd:enumeration value=\"balanced\"/>\n       <xsd:enumeration value=\"soft\"/>\n       <xsd:enumeration value=\"harsh\"/>\n       <xsd:enumeration value=\"flood\"/>\n       <xsd:enumeration value=\"contrasting\"/>\n       <xsd:enumeration value=\"morning\"/>\n       <xsd:enumeration value=\"sunrise\"/>\n       <xsd:enumeration value=\"sunset\"/>\n       <xsd:enumeration value=\"chilly\"/>\n       <xsd:enumeration value=\"freezing\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"twoPt\"/>\n       <xsd:enumeration value=\"glow\"/>\n       <xsd:enumeration value=\"brightRoom\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:simpleType name=\"ST_LightRigDirection\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"tl\"/>\n       <xsd:enumeration value=\"t\"/>\n       <xsd:enumeration value=\"tr\"/>\n       <xsd:enumeration value=\"l\"/>\n       <xsd:enumeration value=\"r\"/>\n       <xsd:enumeration value=\"bl\"/>\n       <xsd:enumeration value=\"b\"/>\n       <xsd:enumeration value=\"br\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_LightRig\">\n     <xsd:sequence>\n       <xsd:element name=\"rot\" type=\"CT_SphereCoords\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rig\" type=\"ST_LightRigType\" use=\"required\"/>\n     <xsd:attribute name=\"dir\" type=\"ST_LightRigDirection\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_BevelPresetType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"relaxedInset\"/>\n       <xsd:enumeration value=\"circle\"/>\n       <xsd:enumeration value=\"slope\"/>\n       <xsd:enumeration value=\"cross\"/>\n       <xsd:enumeration value=\"angle\"/>\n       <xsd:enumeration value=\"softRound\"/>\n       <xsd:enumeration value=\"convex\"/>\n       <xsd:enumeration value=\"coolSlant\"/>\n       <xsd:enumeration value=\"divot\"/>\n       <xsd:enumeration value=\"riblet\"/>\n       <xsd:enumeration value=\"hardEdge\"/>\n       <xsd:enumeration value=\"artDeco\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Bevel\">\n     <xsd:attribute name=\"w\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"h\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prst\" type=\"ST_BevelPresetType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_PresetMaterialType\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:enumeration value=\"legacyMatte\"/>\n       <xsd:enumeration value=\"legacyPlastic\"/>\n       <xsd:enumeration value=\"legacyMetal\"/>\n       <xsd:enumeration value=\"legacyWireframe\"/>\n       <xsd:enumeration value=\"matte\"/>\n       <xsd:enumeration value=\"plastic\"/>\n       <xsd:enumeration value=\"metal\"/>\n       <xsd:enumeration value=\"warmMatte\"/>\n       <xsd:enumeration value=\"translucentPowder\"/>\n       <xsd:enumeration value=\"powder\"/>\n       <xsd:enumeration value=\"dkEdge\"/>\n       <xsd:enumeration value=\"softEdge\"/>\n       <xsd:enumeration value=\"clear\"/>\n       <xsd:enumeration value=\"flat\"/>\n       <xsd:enumeration value=\"softmetal\"/>\n       <xsd:enumeration value=\"none\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Glow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"rad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Shadow\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_ColorChoice\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Reflection\">\n     <xsd:attribute name=\"blurRad\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"stA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"stPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endA\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"endPos\" use=\"optional\" type=\"a:ST_PositiveFixedPercentage\"/>\n     <xsd:attribute name=\"dist\" use=\"optional\" type=\"a:ST_PositiveCoordinate\"/>\n     <xsd:attribute name=\"dir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"fadeDir\" use=\"optional\" type=\"a:ST_PositiveFixedAngle\"/>\n     <xsd:attribute name=\"sx\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"sy\" use=\"optional\" type=\"a:ST_Percentage\"/>\n     <xsd:attribute name=\"kx\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"ky\" use=\"optional\" type=\"a:ST_FixedAngle\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_RectAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_FillTextEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_TextOutlineEffect\">\n     <xsd:sequence>\n       <xsd:group ref=\"EG_FillProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineDashProperties\" minOccurs=\"0\"/>\n       <xsd:group ref=\"EG_LineJoinProperties\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"w\" use=\"optional\" type=\"a:ST_LineWidth\"/>\n     <xsd:attribute name=\"cap\" use=\"optional\" type=\"ST_LineCap\"/>\n     <xsd:attribute name=\"cmpd\" use=\"optional\" type=\"ST_CompoundLine\"/>\n     <xsd:attribute name=\"algn\" use=\"optional\" type=\"ST_PenAlignment\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Scene3D\">\n     <xsd:sequence>\n       <xsd:element name=\"camera\" type=\"CT_Camera\"/>\n       <xsd:element name=\"lightRig\" type=\"CT_LightRig\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Props3D\">\n     <xsd:sequence>\n       <xsd:element name=\"bevelT\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"bevelB\" type=\"CT_Bevel\" minOccurs=\"0\"/>\n       <xsd:element name=\"extrusionClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n       <xsd:element name=\"contourClr\" type=\"CT_Color\" minOccurs=\"0\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"extrusionH\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"contourW\" type=\"a:ST_PositiveCoordinate\" use=\"optional\"/>\n     <xsd:attribute name=\"prstMaterial\" type=\"ST_PresetMaterialType\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrTextEffects\">\n     <xsd:sequence>\n       <xsd:element name=\"glow\" minOccurs=\"0\" type=\"CT_Glow\"/>\n       <xsd:element name=\"shadow\" minOccurs=\"0\" type=\"CT_Shadow\"/>\n       <xsd:element name=\"reflection\" minOccurs=\"0\" type=\"CT_Reflection\"/>\n       <xsd:element name=\"textOutline\" minOccurs=\"0\" type=\"CT_TextOutlineEffect\"/>\n       <xsd:element name=\"textFill\" minOccurs=\"0\" type=\"CT_FillTextEffect\"/>\n       <xsd:element name=\"scene3d\" minOccurs=\"0\" type=\"CT_Scene3D\"/>\n       <xsd:element name=\"props3d\" minOccurs=\"0\" type=\"CT_Props3D\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:simpleType name=\"ST_Ligatures\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"none\"/>\n       <xsd:enumeration value=\"standard\"/>\n       <xsd:enumeration value=\"contextual\"/>\n       <xsd:enumeration value=\"historical\"/>\n       <xsd:enumeration value=\"discretional\"/>\n       <xsd:enumeration value=\"standardContextual\"/>\n       <xsd:enumeration value=\"standardHistorical\"/>\n       <xsd:enumeration value=\"contextualHistorical\"/>\n       <xsd:enumeration value=\"standardDiscretional\"/>\n       <xsd:enumeration value=\"contextualDiscretional\"/>\n       <xsd:enumeration value=\"historicalDiscretional\"/>\n       <xsd:enumeration value=\"standardContextualHistorical\"/>\n       <xsd:enumeration value=\"standardContextualDiscretional\"/>\n       <xsd:enumeration value=\"standardHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"contextualHistoricalDiscretional\"/>\n       <xsd:enumeration value=\"all\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Ligatures\">\n     <xsd:attribute name=\"val\" type=\"ST_Ligatures\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumForm\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"lining\"/>\n       <xsd:enumeration value=\"oldStyle\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumForm\">\n     <xsd:attribute name=\"val\" type=\"ST_NumForm\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_NumSpacing\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"default\"/>\n       <xsd:enumeration value=\"proportional\"/>\n       <xsd:enumeration value=\"tabular\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_NumSpacing\">\n     <xsd:attribute name=\"val\" type=\"ST_NumSpacing\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StyleSet\">\n     <xsd:attribute name=\"id\" type=\"s:ST_UnsignedDecimalNumber\" use=\"required\"/>\n     <xsd:attribute name=\"val\" type=\"ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_StylisticSets\">\n     <xsd:sequence minOccurs=\"0\">\n       <xsd:element name=\"styleSet\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"CT_StyleSet\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:group name=\"EG_RPrOpenType\">\n     <xsd:sequence>\n       <xsd:element name=\"ligatures\" minOccurs=\"0\" type=\"CT_Ligatures\"/>\n       <xsd:element name=\"numForm\" minOccurs=\"0\" type=\"CT_NumForm\"/>\n       <xsd:element name=\"numSpacing\" minOccurs=\"0\" type=\"CT_NumSpacing\"/>\n       <xsd:element name=\"stylisticSets\" minOccurs=\"0\" type=\"CT_StylisticSets\"/>\n       <xsd:element name=\"cntxtAlts\" minOccurs=\"0\" type=\"CT_OnOff\"/>\n     </xsd:sequence>\n   </xsd:group>\n   <xsd:element name=\"discardImageEditingData\" type=\"CT_OnOff\"/>\n   <xsd:element name=\"defaultImageDpi\" type=\"CT_DefaultImageDpi\"/>\n   <xsd:complexType name=\"CT_DefaultImageDpi\">\n     <xsd:attribute name=\"val\" type=\"w:ST_DecimalNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"entityPicker\" type=\"w:CT_Empty\"/>\n   <xsd:complexType name=\"CT_SdtCheckboxSymbol\">\n     <xsd:attribute name=\"font\" type=\"s:ST_String\"/>\n     <xsd:attribute name=\"val\" type=\"w:ST_ShortHexNumber\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_SdtCheckbox\">\n     <xsd:sequence>\n       <xsd:element name=\"checked\" type=\"CT_OnOff\" minOccurs=\"0\"/>\n       <xsd:element name=\"checkedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n       <xsd:element name=\"uncheckedState\" type=\"CT_SdtCheckboxSymbol\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:element name=\"checkbox\" type=\"CT_SdtCheckbox\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2012/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2012/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:element name=\"color\" type=\"w12:CT_Color\"/>\n   <xsd:simpleType name=\"ST_SdtAppearance\">\n     <xsd:restriction base=\"xsd:string\">\n       <xsd:enumeration value=\"boundingBox\"/>\n       <xsd:enumeration value=\"tags\"/>\n       <xsd:enumeration value=\"hidden\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:element name=\"dataBinding\" type=\"w12:CT_DataBinding\"/>\n   <xsd:complexType name=\"CT_SdtAppearance\">\n     <xsd:attribute name=\"val\" type=\"ST_SdtAppearance\"/>\n   </xsd:complexType>\n   <xsd:element name=\"appearance\" type=\"CT_SdtAppearance\"/>\n   <xsd:complexType name=\"CT_CommentsEx\">\n     <xsd:sequence>\n       <xsd:element name=\"commentEx\" type=\"CT_CommentEx\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentEx\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"paraIdParent\" type=\"w12:ST_LongHexNumber\" use=\"optional\"/>\n     <xsd:attribute name=\"done\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsEx\" type=\"CT_CommentsEx\"/>\n   <xsd:complexType name=\"CT_People\">\n     <xsd:sequence>\n       <xsd:element name=\"person\" type=\"CT_Person\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_PresenceInfo\">\n     <xsd:attribute name=\"providerId\" type=\"xsd:string\" use=\"required\"/>\n     <xsd:attribute name=\"userId\" type=\"xsd:string\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_Person\">\n     <xsd:sequence>\n       <xsd:element name=\"presenceInfo\" type=\"CT_PresenceInfo\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"author\" type=\"s:ST_String\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"people\" type=\"CT_People\"/>\n   <xsd:complexType name=\"CT_SdtRepeatedSection\">\n     <xsd:sequence>\n       <xsd:element name=\"sectionTitle\" type=\"w12:CT_String\" minOccurs=\"0\"/>\n       <xsd:element name=\"doNotAllowInsertDeleteSection\" type=\"w12:CT_OnOff\" minOccurs=\"0\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:simpleType name=\"ST_Guid\">\n     <xsd:restriction base=\"xsd:token\">\n       <xsd:pattern value=\"\\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\\}\"/>\n     </xsd:restriction>\n   </xsd:simpleType>\n   <xsd:complexType name=\"CT_Guid\">\n     <xsd:attribute name=\"val\" type=\"ST_Guid\"/>\n   </xsd:complexType>\n   <xsd:element name=\"repeatingSection\" type=\"CT_SdtRepeatedSection\"/>\n   <xsd:element name=\"repeatingSectionItem\" type=\"w12:CT_Empty\"/>\n   <xsd:element name=\"chartTrackingRefBased\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"collapsed\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"docId\" type=\"CT_Guid\"/>\n   <xsd:element name=\"footnoteColumns\" type=\"w12:CT_DecimalNumber\"/>\n   <xsd:element name=\"webExtensionLinked\" type=\"w12:CT_OnOff\"/>\n   <xsd:element name=\"webExtensionCreated\" type=\"w12:CT_OnOff\"/>\n   <xsd:attribute name=\"restartNumberingAfterBreak\" type=\"s:ST_OnOff\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_Extension\">\n     <xsd:sequence>\n       <xsd:any processContents=\"lax\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"uri\" type=\"xsd:token\"/>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_ExtensionList\">\n     <xsd:sequence>\n       <xsd:element name=\"ext\" type=\"CT_Extension\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:s=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\">\n   <xsd:import id=\"w16\" namespace=\"http://schemas.microsoft.com/office/word/2018/wordml\" schemaLocation=\"wml-2018.xsd\"/>\n   <xsd:import id=\"w\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:import id=\"s\" namespace=\"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\" schemaLocation=\"../ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"commentExtensible\" type=\"CT_CommentExtensible\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentExtensible\">\n     <xsd:sequence>\n       <xsd:element name=\"extLst\" type=\"w16:CT_ExtensionList\" minOccurs=\"0\" maxOccurs=\"1\"/>\n     </xsd:sequence>\n     <xsd:attribute name=\"durableId\" type=\"w:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"dateUtc\" type=\"w:ST_DateTime\" use=\"optional\"/>\n     <xsd:attribute name=\"intelligentPlaceholder\" type=\"s:ST_OnOff\" use=\"optional\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsExtensible\" type=\"CT_CommentsExtensible\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" targetNamespace=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_CommentsIds\">\n     <xsd:sequence>\n       <xsd:element name=\"commentId\" type=\"CT_CommentId\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n     </xsd:sequence>\n   </xsd:complexType>\n   <xsd:complexType name=\"CT_CommentId\">\n     <xsd:attribute name=\"paraId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n     <xsd:attribute name=\"durableId\" type=\"w12:ST_LongHexNumber\" use=\"required\"/>\n   </xsd:complexType>\n   <xsd:element name=\"commentsIds\" type=\"CT_CommentsIds\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" targetNamespace=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:attribute name=\"storeItemChecksum\" type=\"w12:ST_String\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd",
    "content": " <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:w12=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" elementFormDefault=\"qualified\" attributeFormDefault=\"qualified\" blockDefault=\"#all\" xmlns=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" targetNamespace=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\">\n   <xsd:import id=\"w12\" namespace=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" schemaLocation=\"../ISO-IEC29500-4_2016/wml.xsd\"/>\n   <xsd:complexType name=\"CT_SymEx\">\n     <xsd:attribute name=\"font\" type=\"w12:ST_String\"/>\n     <xsd:attribute name=\"char\" type=\"w12:ST_LongHexNumber\"/>\n   </xsd:complexType>\n   <xsd:element name=\"symEx\" type=\"CT_SymEx\"/>\n </xsd:schema>\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/pack.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nTool to pack a directory into a .docx, .pptx, or .xlsx file with XML formatting undone.\n\nExample usage:\n    python pack.py <input_directory> <office_file> [--force]\n\"\"\"\n\nimport argparse\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport defusedxml.minidom\nimport zipfile\nfrom pathlib import Path\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Pack a directory into an Office file\")\n    parser.add_argument(\"input_directory\", help=\"Unpacked Office document directory\")\n    parser.add_argument(\"output_file\", help=\"Output Office file (.docx/.pptx/.xlsx)\")\n    parser.add_argument(\"--force\", action=\"store_true\", help=\"Skip validation\")\n    args = parser.parse_args()\n\n    try:\n        success = pack_document(\n            args.input_directory, args.output_file, validate=not args.force\n        )\n\n        # Show warning if validation was skipped\n        if args.force:\n            print(\"Warning: Skipped validation, file may be corrupt\", file=sys.stderr)\n        # Exit with error if validation failed\n        elif not success:\n            print(\"Contents would produce a corrupt file.\", file=sys.stderr)\n            print(\"Please validate XML before repacking.\", file=sys.stderr)\n            print(\"Use --force to skip validation and pack anyway.\", file=sys.stderr)\n            sys.exit(1)\n\n    except ValueError as e:\n        sys.exit(f\"Error: {e}\")\n\n\ndef pack_document(input_dir, output_file, validate=False):\n    \"\"\"Pack a directory into an Office file (.docx/.pptx/.xlsx).\n\n    Args:\n        input_dir: Path to unpacked Office document directory\n        output_file: Path to output Office file\n        validate: If True, validates with soffice (default: False)\n\n    Returns:\n        bool: True if successful, False if validation failed\n    \"\"\"\n    input_dir = Path(input_dir)\n    output_file = Path(output_file)\n\n    if not input_dir.is_dir():\n        raise ValueError(f\"{input_dir} is not a directory\")\n    if output_file.suffix.lower() not in {\".docx\", \".pptx\", \".xlsx\"}:\n        raise ValueError(f\"{output_file} must be a .docx, .pptx, or .xlsx file\")\n\n    # Work in temporary directory to avoid modifying original\n    with tempfile.TemporaryDirectory() as temp_dir:\n        temp_content_dir = Path(temp_dir) / \"content\"\n        shutil.copytree(input_dir, temp_content_dir)\n\n        # Process XML files to remove pretty-printing whitespace\n        for pattern in [\"*.xml\", \"*.rels\"]:\n            for xml_file in temp_content_dir.rglob(pattern):\n                condense_xml(xml_file)\n\n        # Create final Office file as zip archive\n        output_file.parent.mkdir(parents=True, exist_ok=True)\n        with zipfile.ZipFile(output_file, \"w\", zipfile.ZIP_DEFLATED) as zf:\n            for f in temp_content_dir.rglob(\"*\"):\n                if f.is_file():\n                    zf.write(f, f.relative_to(temp_content_dir))\n\n        # Validate if requested\n        if validate:\n            if not validate_document(output_file):\n                output_file.unlink()  # Delete the corrupt file\n                return False\n\n    return True\n\n\ndef validate_document(doc_path):\n    \"\"\"Validate document by converting to HTML with soffice.\"\"\"\n    # Determine the correct filter based on file extension\n    match doc_path.suffix.lower():\n        case \".docx\":\n            filter_name = \"html:HTML\"\n        case \".pptx\":\n            filter_name = \"html:impress_html_Export\"\n        case \".xlsx\":\n            filter_name = \"html:HTML (StarCalc)\"\n\n    with tempfile.TemporaryDirectory() as temp_dir:\n        try:\n            result = subprocess.run(\n                [\n                    \"soffice\",\n                    \"--headless\",\n                    \"--convert-to\",\n                    filter_name,\n                    \"--outdir\",\n                    temp_dir,\n                    str(doc_path),\n                ],\n                capture_output=True,\n                timeout=10,\n                text=True,\n            )\n            if not (Path(temp_dir) / f\"{doc_path.stem}.html\").exists():\n                error_msg = result.stderr.strip() or \"Document validation failed\"\n                print(f\"Validation error: {error_msg}\", file=sys.stderr)\n                return False\n            return True\n        except FileNotFoundError:\n            print(\"Warning: soffice not found. Skipping validation.\", file=sys.stderr)\n            return True\n        except subprocess.TimeoutExpired:\n            print(\"Validation error: Timeout during conversion\", file=sys.stderr)\n            return False\n        except Exception as e:\n            print(f\"Validation error: {e}\", file=sys.stderr)\n            return False\n\n\ndef condense_xml(xml_file):\n    \"\"\"Strip unnecessary whitespace and remove comments.\"\"\"\n    with open(xml_file, \"r\", encoding=\"utf-8\") as f:\n        dom = defusedxml.minidom.parse(f)\n\n    # Process each element to remove whitespace and comments\n    for element in dom.getElementsByTagName(\"*\"):\n        # Skip w:t elements and their processing\n        if element.tagName.endswith(\":t\"):\n            continue\n\n        # Remove whitespace-only text nodes and comment nodes\n        for child in list(element.childNodes):\n            if (\n                child.nodeType == child.TEXT_NODE\n                and child.nodeValue\n                and child.nodeValue.strip() == \"\"\n            ) or child.nodeType == child.COMMENT_NODE:\n                element.removeChild(child)\n\n    # Write back the condensed XML\n    with open(xml_file, \"wb\") as f:\n        f.write(dom.toxml(encoding=\"UTF-8\"))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/unpack.py",
    "content": "#!/usr/bin/env python3\n\"\"\"Unpack and format XML contents of Office files (.docx, .pptx, .xlsx)\"\"\"\n\nimport random\nimport sys\nimport defusedxml.minidom\nimport zipfile\nfrom pathlib import Path\n\n# Get command line arguments\nassert len(sys.argv) == 3, \"Usage: python unpack.py <office_file> <output_dir>\"\ninput_file, output_dir = sys.argv[1], sys.argv[2]\n\n# Extract and format\noutput_path = Path(output_dir)\noutput_path.mkdir(parents=True, exist_ok=True)\nzipfile.ZipFile(input_file).extractall(output_path)\n\n# Pretty print all XML files\nxml_files = list(output_path.rglob(\"*.xml\")) + list(output_path.rglob(\"*.rels\"))\nfor xml_file in xml_files:\n    content = xml_file.read_text(encoding=\"utf-8\")\n    dom = defusedxml.minidom.parseString(content)\n    xml_file.write_bytes(dom.toprettyxml(indent=\"  \", encoding=\"ascii\"))\n\n# For .docx files, suggest an RSID for tracked changes\nif input_file.endswith(\".docx\"):\n    suggested_rsid = \"\".join(random.choices(\"0123456789ABCDEF\", k=8))\n    print(f\"Suggested RSID for edit session: {suggested_rsid}\")\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validate.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nCommand line tool to validate Office document XML files against XSD schemas and tracked changes.\n\nUsage:\n    python validate.py <dir> --original <original_file>\n\"\"\"\n\nimport argparse\nimport sys\nfrom pathlib import Path\n\nfrom validation import DOCXSchemaValidator, PPTXSchemaValidator, RedliningValidator\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Validate Office document XML files\")\n    parser.add_argument(\n        \"unpacked_dir\",\n        help=\"Path to unpacked Office document directory\",\n    )\n    parser.add_argument(\n        \"--original\",\n        required=True,\n        help=\"Path to original file (.docx/.pptx/.xlsx)\",\n    )\n    parser.add_argument(\n        \"-v\",\n        \"--verbose\",\n        action=\"store_true\",\n        help=\"Enable verbose output\",\n    )\n    args = parser.parse_args()\n\n    # Validate paths\n    unpacked_dir = Path(args.unpacked_dir)\n    original_file = Path(args.original)\n    file_extension = original_file.suffix.lower()\n    assert unpacked_dir.is_dir(), f\"Error: {unpacked_dir} is not a directory\"\n    assert original_file.is_file(), f\"Error: {original_file} is not a file\"\n    assert file_extension in [\".docx\", \".pptx\", \".xlsx\"], (\n        f\"Error: {original_file} must be a .docx, .pptx, or .xlsx file\"\n    )\n\n    # Run validations\n    match file_extension:\n        case \".docx\":\n            validators = [DOCXSchemaValidator, RedliningValidator]\n        case \".pptx\":\n            validators = [PPTXSchemaValidator]\n        case _:\n            print(f\"Error: Validation not supported for file type {file_extension}\")\n            sys.exit(1)\n\n    # Run validators\n    success = True\n    for V in validators:\n        validator = V(unpacked_dir, original_file, verbose=args.verbose)\n        if not validator.validate():\n            success = False\n\n    if success:\n        print(\"All validations PASSED!\")\n\n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validation/__init__.py",
    "content": "\"\"\"\nValidation modules for Word document processing.\n\"\"\"\n\nfrom .base import BaseSchemaValidator\nfrom .docx import DOCXSchemaValidator\nfrom .pptx import PPTXSchemaValidator\nfrom .redlining import RedliningValidator\n\n__all__ = [\n    \"BaseSchemaValidator\",\n    \"DOCXSchemaValidator\",\n    \"PPTXSchemaValidator\",\n    \"RedliningValidator\",\n]\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validation/base.py",
    "content": "\"\"\"\nBase validator with common validation logic for document files.\n\"\"\"\n\nimport re\nfrom pathlib import Path\n\nimport lxml.etree\n\n\nclass BaseSchemaValidator:\n    \"\"\"Base validator with common validation logic for document files.\"\"\"\n\n    # Elements whose 'id' attributes must be unique within their file\n    # Format: element_name -> (attribute_name, scope)\n    # scope can be 'file' (unique within file) or 'global' (unique across all files)\n    UNIQUE_ID_REQUIREMENTS = {\n        # Word elements\n        \"comment\": (\"id\", \"file\"),  # Comment IDs in comments.xml\n        \"commentrangestart\": (\"id\", \"file\"),  # Must match comment IDs\n        \"commentrangeend\": (\"id\", \"file\"),  # Must match comment IDs\n        \"bookmarkstart\": (\"id\", \"file\"),  # Bookmark start IDs\n        \"bookmarkend\": (\"id\", \"file\"),  # Bookmark end IDs\n        # Note: ins and del (track changes) can share IDs when part of same revision\n        # PowerPoint elements\n        \"sldid\": (\"id\", \"file\"),  # Slide IDs in presentation.xml\n        \"sldmasterid\": (\"id\", \"global\"),  # Slide master IDs must be globally unique\n        \"sldlayoutid\": (\"id\", \"global\"),  # Slide layout IDs must be globally unique\n        \"cm\": (\"authorid\", \"file\"),  # Comment author IDs\n        # Excel elements\n        \"sheet\": (\"sheetid\", \"file\"),  # Sheet IDs in workbook.xml\n        \"definedname\": (\"id\", \"file\"),  # Named range IDs\n        # Drawing/Shape elements (all formats)\n        \"cxnsp\": (\"id\", \"file\"),  # Connection shape IDs\n        \"sp\": (\"id\", \"file\"),  # Shape IDs\n        \"pic\": (\"id\", \"file\"),  # Picture IDs\n        \"grpsp\": (\"id\", \"file\"),  # Group shape IDs\n    }\n\n    # Mapping of element names to expected relationship types\n    # Subclasses should override this with format-specific mappings\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    # Unified schema mappings for all Office document types\n    SCHEMA_MAPPINGS = {\n        # Document type specific schemas\n        \"word\": \"ISO-IEC29500-4_2016/wml.xsd\",  # Word documents\n        \"ppt\": \"ISO-IEC29500-4_2016/pml.xsd\",  # PowerPoint presentations\n        \"xl\": \"ISO-IEC29500-4_2016/sml.xsd\",  # Excel spreadsheets\n        # Common file types\n        \"[Content_Types].xml\": \"ecma/fouth-edition/opc-contentTypes.xsd\",\n        \"app.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd\",\n        \"core.xml\": \"ecma/fouth-edition/opc-coreProperties.xsd\",\n        \"custom.xml\": \"ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd\",\n        \".rels\": \"ecma/fouth-edition/opc-relationships.xsd\",\n        # Word-specific files\n        \"people.xml\": \"microsoft/wml-2012.xsd\",\n        \"commentsIds.xml\": \"microsoft/wml-cid-2016.xsd\",\n        \"commentsExtensible.xml\": \"microsoft/wml-cex-2018.xsd\",\n        \"commentsExtended.xml\": \"microsoft/wml-2012.xsd\",\n        # Chart files (common across document types)\n        \"chart\": \"ISO-IEC29500-4_2016/dml-chart.xsd\",\n        # Theme files (common across document types)\n        \"theme\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n        # Drawing and media files\n        \"drawing\": \"ISO-IEC29500-4_2016/dml-main.xsd\",\n    }\n\n    # Unified namespace constants\n    MC_NAMESPACE = \"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    XML_NAMESPACE = \"http://www.w3.org/XML/1998/namespace\"\n\n    # Common OOXML namespaces used across validators\n    PACKAGE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/relationships\"\n    )\n    OFFICE_RELATIONSHIPS_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n    )\n    CONTENT_TYPES_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/package/2006/content-types\"\n    )\n\n    # Folders where we should clean ignorable namespaces\n    MAIN_CONTENT_FOLDERS = {\"word\", \"ppt\", \"xl\"}\n\n    # All allowed OOXML namespaces (superset of all document types)\n    OOXML_NAMESPACES = {\n        \"http://schemas.openxmlformats.org/officeDocument/2006/math\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\",\n        \"http://schemas.openxmlformats.org/schemaLibrary/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/main\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chart\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/diagram\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/picture\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\",\n        \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\",\n        \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\",\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\",\n        \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\",\n        \"http://schemas.openxmlformats.org/officeDocument/2006/sharedTypes\",\n        \"http://www.w3.org/XML/1998/namespace\",\n    }\n\n    def __init__(self, unpacked_dir, original_file, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir).resolve()\n        self.original_file = Path(original_file)\n        self.verbose = verbose\n\n        # Set schemas directory\n        self.schemas_dir = Path(__file__).parent.parent.parent / \"schemas\"\n\n        # Get all XML and .rels files\n        patterns = [\"*.xml\", \"*.rels\"]\n        self.xml_files = [\n            f for pattern in patterns for f in self.unpacked_dir.rglob(pattern)\n        ]\n\n        if not self.xml_files:\n            print(f\"Warning: No XML files found in {self.unpacked_dir}\")\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        raise NotImplementedError(\"Subclasses must implement the validate method\")\n\n    def validate_xml(self):\n        \"\"\"Validate that all XML files are well-formed.\"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                # Try to parse the XML file\n                lxml.etree.parse(str(xml_file))\n            except lxml.etree.XMLSyntaxError as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Line {e.lineno}: {e.msg}\"\n                )\n            except Exception as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                    f\"Unexpected error: {str(e)}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} XML violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All XML files are well-formed\")\n            return True\n\n    def validate_namespaces(self):\n        \"\"\"Validate that namespace prefixes in Ignorable attributes are declared.\"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                declared = set(root.nsmap.keys()) - {None}  # Exclude default namespace\n\n                for attr_val in [\n                    v for k, v in root.attrib.items() if k.endswith(\"Ignorable\")\n                ]:\n                    undeclared = set(attr_val.split()) - declared\n                    errors.extend(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Namespace '{ns}' in Ignorable but not declared\"\n                        for ns in undeclared\n                    )\n            except lxml.etree.XMLSyntaxError:\n                continue\n\n        if errors:\n            print(f\"FAILED - {len(errors)} namespace issues:\")\n            for error in errors:\n                print(error)\n            return False\n        if self.verbose:\n            print(\"PASSED - All namespace prefixes properly declared\")\n        return True\n\n    def validate_unique_ids(self):\n        \"\"\"Validate that specific IDs are unique according to OOXML requirements.\"\"\"\n        errors = []\n        global_ids = {}  # Track globally unique IDs across all files\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                file_ids = {}  # Track IDs that must be unique within this file\n\n                # Remove all mc:AlternateContent elements from the tree\n                mc_elements = root.xpath(\n                    \".//mc:AlternateContent\", namespaces={\"mc\": self.MC_NAMESPACE}\n                )\n                for elem in mc_elements:\n                    elem.getparent().remove(elem)\n\n                # Now check IDs in the cleaned tree\n                for elem in root.iter():\n                    # Get the element name without namespace\n                    tag = (\n                        elem.tag.split(\"}\")[-1].lower()\n                        if \"}\" in elem.tag\n                        else elem.tag.lower()\n                    )\n\n                    # Check if this element type has ID uniqueness requirements\n                    if tag in self.UNIQUE_ID_REQUIREMENTS:\n                        attr_name, scope = self.UNIQUE_ID_REQUIREMENTS[tag]\n\n                        # Look for the specified attribute\n                        id_value = None\n                        for attr, value in elem.attrib.items():\n                            attr_local = (\n                                attr.split(\"}\")[-1].lower()\n                                if \"}\" in attr\n                                else attr.lower()\n                            )\n                            if attr_local == attr_name:\n                                id_value = value\n                                break\n\n                        if id_value is not None:\n                            if scope == \"global\":\n                                # Check global uniqueness\n                                if id_value in global_ids:\n                                    prev_file, prev_line, prev_tag = global_ids[\n                                        id_value\n                                    ]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Global ID '{id_value}' in <{tag}> \"\n                                        f\"already used in {prev_file} at line {prev_line} in <{prev_tag}>\"\n                                    )\n                                else:\n                                    global_ids[id_value] = (\n                                        xml_file.relative_to(self.unpacked_dir),\n                                        elem.sourceline,\n                                        tag,\n                                    )\n                            elif scope == \"file\":\n                                # Check file-level uniqueness\n                                key = (tag, attr_name)\n                                if key not in file_ids:\n                                    file_ids[key] = {}\n\n                                if id_value in file_ids[key]:\n                                    prev_line = file_ids[key][id_value]\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: Duplicate {attr_name}='{id_value}' in <{tag}> \"\n                                        f\"(first occurrence at line {prev_line})\"\n                                    )\n                                else:\n                                    file_ids[key][id_value] = elem.sourceline\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} ID uniqueness violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All required IDs are unique\")\n            return True\n\n    def validate_file_references(self):\n        \"\"\"\n        Validate that all .rels files properly reference files and that all files are referenced.\n        \"\"\"\n        errors = []\n\n        # Find all .rels files\n        rels_files = list(self.unpacked_dir.rglob(\"*.rels\"))\n\n        if not rels_files:\n            if self.verbose:\n                print(\"PASSED - No .rels files found\")\n            return True\n\n        # Get all files in the unpacked directory (excluding reference files)\n        all_files = []\n        for file_path in self.unpacked_dir.rglob(\"*\"):\n            if (\n                file_path.is_file()\n                and file_path.name != \"[Content_Types].xml\"\n                and not file_path.name.endswith(\".rels\")\n            ):  # This file is not referenced by .rels\n                all_files.append(file_path.resolve())\n\n        # Track all files that are referenced by any .rels file\n        all_referenced_files = set()\n\n        if self.verbose:\n            print(\n                f\"Found {len(rels_files)} .rels files and {len(all_files)} target files\"\n            )\n\n        # Check each .rels file\n        for rels_file in rels_files:\n            try:\n                # Parse relationships file\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Get the directory where this .rels file is located\n                rels_dir = rels_file.parent\n\n                # Find all relationships and their targets\n                referenced_files = set()\n                broken_refs = []\n\n                for rel in rels_root.findall(\n                    \".//ns:Relationship\",\n                    namespaces={\"ns\": self.PACKAGE_RELATIONSHIPS_NAMESPACE},\n                ):\n                    target = rel.get(\"Target\")\n                    if target and not target.startswith(\n                        (\"http\", \"mailto:\")\n                    ):  # Skip external URLs\n                        # Resolve the target path relative to the .rels file location\n                        if rels_file.name == \".rels\":\n                            # Root .rels file - targets are relative to unpacked_dir\n                            target_path = self.unpacked_dir / target\n                        else:\n                            # Other .rels files - targets are relative to their parent's parent\n                            # e.g., word/_rels/document.xml.rels -> targets relative to word/\n                            base_dir = rels_dir.parent\n                            target_path = base_dir / target\n\n                        # Normalize the path and check if it exists\n                        try:\n                            target_path = target_path.resolve()\n                            if target_path.exists() and target_path.is_file():\n                                referenced_files.add(target_path)\n                                all_referenced_files.add(target_path)\n                            else:\n                                broken_refs.append((target, rel.sourceline))\n                        except (OSError, ValueError):\n                            broken_refs.append((target, rel.sourceline))\n\n                # Report broken references\n                if broken_refs:\n                    rel_path = rels_file.relative_to(self.unpacked_dir)\n                    for broken_ref, line_num in broken_refs:\n                        errors.append(\n                            f\"  {rel_path}: Line {line_num}: Broken reference to {broken_ref}\"\n                        )\n\n            except Exception as e:\n                rel_path = rels_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error parsing {rel_path}: {e}\")\n\n        # Check for unreferenced files (files that exist but are not referenced anywhere)\n        unreferenced_files = set(all_files) - all_referenced_files\n\n        if unreferenced_files:\n            for unref_file in sorted(unreferenced_files):\n                unref_rel_path = unref_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Unreferenced file: {unref_rel_path}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"CRITICAL: These errors will cause the document to appear corrupt. \"\n                + \"Broken references MUST be fixed, \"\n                + \"and unreferenced files MUST be referenced or removed.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All references are valid and all files are properly referenced\"\n                )\n            return True\n\n    def validate_all_relationship_ids(self):\n        \"\"\"\n        Validate that all r:id attributes in XML files reference existing IDs\n        in their corresponding .rels files, and optionally validate relationship types.\n        \"\"\"\n        import lxml.etree\n\n        errors = []\n\n        # Process each XML file that might contain r:id references\n        for xml_file in self.xml_files:\n            # Skip .rels files themselves\n            if xml_file.suffix == \".rels\":\n                continue\n\n            # Determine the corresponding .rels file\n            # For dir/file.xml, it's dir/_rels/file.xml.rels\n            rels_dir = xml_file.parent / \"_rels\"\n            rels_file = rels_dir / f\"{xml_file.name}.rels\"\n\n            # Skip if there's no corresponding .rels file (that's okay)\n            if not rels_file.exists():\n                continue\n\n            try:\n                # Parse the .rels file to get valid relationship IDs and their types\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n                rid_to_type = {}\n\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rid = rel.get(\"Id\")\n                    rel_type = rel.get(\"Type\", \"\")\n                    if rid:\n                        # Check for duplicate rIds\n                        if rid in rid_to_type:\n                            rels_rel_path = rels_file.relative_to(self.unpacked_dir)\n                            errors.append(\n                                f\"  {rels_rel_path}: Line {rel.sourceline}: \"\n                                f\"Duplicate relationship ID '{rid}' (IDs must be unique)\"\n                            )\n                        # Extract just the type name from the full URL\n                        type_name = (\n                            rel_type.split(\"/\")[-1] if \"/\" in rel_type else rel_type\n                        )\n                        rid_to_type[rid] = type_name\n\n                # Parse the XML file to find all r:id references\n                xml_root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all elements with r:id attributes\n                for elem in xml_root.iter():\n                    # Check for r:id attribute (relationship ID)\n                    rid_attr = elem.get(f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\")\n                    if rid_attr:\n                        xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                        elem_name = (\n                            elem.tag.split(\"}\")[-1] if \"}\" in elem.tag else elem.tag\n                        )\n\n                        # Check if the ID exists\n                        if rid_attr not in rid_to_type:\n                            errors.append(\n                                f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                f\"<{elem_name}> references non-existent relationship '{rid_attr}' \"\n                                f\"(valid IDs: {', '.join(sorted(rid_to_type.keys())[:5])}{'...' if len(rid_to_type) > 5 else ''})\"\n                            )\n                        # Check if we have type expectations for this element\n                        elif self.ELEMENT_RELATIONSHIP_TYPES:\n                            expected_type = self._get_expected_relationship_type(\n                                elem_name\n                            )\n                            if expected_type:\n                                actual_type = rid_to_type[rid_attr]\n                                # Check if the actual type matches or contains the expected type\n                                if expected_type not in actual_type.lower():\n                                    errors.append(\n                                        f\"  {xml_rel_path}: Line {elem.sourceline}: \"\n                                        f\"<{elem_name}> references '{rid_attr}' which points to '{actual_type}' \"\n                                        f\"but should point to a '{expected_type}' relationship\"\n                                    )\n\n            except Exception as e:\n                xml_rel_path = xml_file.relative_to(self.unpacked_dir)\n                errors.append(f\"  Error processing {xml_rel_path}: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} relationship ID reference errors:\")\n            for error in errors:\n                print(error)\n            print(\"\\nThese ID mismatches will cause the document to appear corrupt!\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All relationship ID references are valid\")\n            return True\n\n    def _get_expected_relationship_type(self, element_name):\n        \"\"\"\n        Get the expected relationship type for an element.\n        First checks the explicit mapping, then tries pattern detection.\n        \"\"\"\n        # Normalize element name to lowercase\n        elem_lower = element_name.lower()\n\n        # Check explicit mapping first\n        if elem_lower in self.ELEMENT_RELATIONSHIP_TYPES:\n            return self.ELEMENT_RELATIONSHIP_TYPES[elem_lower]\n\n        # Try pattern detection for common patterns\n        # Pattern 1: Elements ending in \"Id\" often expect a relationship of the prefix type\n        if elem_lower.endswith(\"id\") and len(elem_lower) > 2:\n            # e.g., \"sldId\" -> \"sld\", \"sldMasterId\" -> \"sldMaster\"\n            prefix = elem_lower[:-2]  # Remove \"id\"\n            # Check if this might be a compound like \"sldMasterId\"\n            if prefix.endswith(\"master\"):\n                return prefix.lower()\n            elif prefix.endswith(\"layout\"):\n                return prefix.lower()\n            else:\n                # Simple case like \"sldId\" -> \"slide\"\n                # Common transformations\n                if prefix == \"sld\":\n                    return \"slide\"\n                return prefix.lower()\n\n        # Pattern 2: Elements ending in \"Reference\" expect a relationship of the prefix type\n        if elem_lower.endswith(\"reference\") and len(elem_lower) > 9:\n            prefix = elem_lower[:-9]  # Remove \"reference\"\n            return prefix.lower()\n\n        return None\n\n    def validate_content_types(self):\n        \"\"\"Validate that all content files are properly declared in [Content_Types].xml.\"\"\"\n        errors = []\n\n        # Find [Content_Types].xml file\n        content_types_file = self.unpacked_dir / \"[Content_Types].xml\"\n        if not content_types_file.exists():\n            print(\"FAILED - [Content_Types].xml file not found\")\n            return False\n\n        try:\n            # Parse and get all declared parts and extensions\n            root = lxml.etree.parse(str(content_types_file)).getroot()\n            declared_parts = set()\n            declared_extensions = set()\n\n            # Get Override declarations (specific files)\n            for override in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Override\"\n            ):\n                part_name = override.get(\"PartName\")\n                if part_name is not None:\n                    declared_parts.add(part_name.lstrip(\"/\"))\n\n            # Get Default declarations (by extension)\n            for default in root.findall(\n                f\".//{{{self.CONTENT_TYPES_NAMESPACE}}}Default\"\n            ):\n                extension = default.get(\"Extension\")\n                if extension is not None:\n                    declared_extensions.add(extension.lower())\n\n            # Root elements that require content type declaration\n            declarable_roots = {\n                \"sld\",\n                \"sldLayout\",\n                \"sldMaster\",\n                \"presentation\",  # PowerPoint\n                \"document\",  # Word\n                \"workbook\",\n                \"worksheet\",  # Excel\n                \"theme\",  # Common\n            }\n\n            # Common media file extensions that should be declared\n            media_extensions = {\n                \"png\": \"image/png\",\n                \"jpg\": \"image/jpeg\",\n                \"jpeg\": \"image/jpeg\",\n                \"gif\": \"image/gif\",\n                \"bmp\": \"image/bmp\",\n                \"tiff\": \"image/tiff\",\n                \"wmf\": \"image/x-wmf\",\n                \"emf\": \"image/x-emf\",\n            }\n\n            # Get all files in the unpacked directory\n            all_files = list(self.unpacked_dir.rglob(\"*\"))\n            all_files = [f for f in all_files if f.is_file()]\n\n            # Check all XML files for Override declarations\n            for xml_file in self.xml_files:\n                path_str = str(xml_file.relative_to(self.unpacked_dir)).replace(\n                    \"\\\\\", \"/\"\n                )\n\n                # Skip non-content files\n                if any(\n                    skip in path_str\n                    for skip in [\".rels\", \"[Content_Types]\", \"docProps/\", \"_rels/\"]\n                ):\n                    continue\n\n                try:\n                    root_tag = lxml.etree.parse(str(xml_file)).getroot().tag\n                    root_name = root_tag.split(\"}\")[-1] if \"}\" in root_tag else root_tag\n\n                    if root_name in declarable_roots and path_str not in declared_parts:\n                        errors.append(\n                            f\"  {path_str}: File with <{root_name}> root not declared in [Content_Types].xml\"\n                        )\n\n                except Exception:\n                    continue  # Skip unparseable files\n\n            # Check all non-XML files for Default extension declarations\n            for file_path in all_files:\n                # Skip XML files and metadata files (already checked above)\n                if file_path.suffix.lower() in {\".xml\", \".rels\"}:\n                    continue\n                if file_path.name == \"[Content_Types].xml\":\n                    continue\n                if \"_rels\" in file_path.parts or \"docProps\" in file_path.parts:\n                    continue\n\n                extension = file_path.suffix.lstrip(\".\").lower()\n                if extension and extension not in declared_extensions:\n                    # Check if it's a known media extension that should be declared\n                    if extension in media_extensions:\n                        relative_path = file_path.relative_to(self.unpacked_dir)\n                        errors.append(\n                            f'  {relative_path}: File with extension \\'{extension}\\' not declared in [Content_Types].xml - should add: <Default Extension=\"{extension}\" ContentType=\"{media_extensions[extension]}\"/>'\n                        )\n\n        except Exception as e:\n            errors.append(f\"  Error parsing [Content_Types].xml: {e}\")\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} content type declaration errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\n                    \"PASSED - All content files are properly declared in [Content_Types].xml\"\n                )\n            return True\n\n    def validate_file_against_xsd(self, xml_file, verbose=False):\n        \"\"\"Validate a single XML file against XSD schema, comparing with original.\n\n        Args:\n            xml_file: Path to XML file to validate\n            verbose: Enable verbose output\n\n        Returns:\n            tuple: (is_valid, new_errors_set) where is_valid is True/False/None (skipped)\n        \"\"\"\n        # Resolve both paths to handle symlinks\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n\n        # Validate current file\n        is_valid, current_errors = self._validate_single_file_xsd(\n            xml_file, unpacked_dir\n        )\n\n        if is_valid is None:\n            return None, set()  # Skipped\n        elif is_valid:\n            return True, set()  # Valid, no errors\n\n        # Get errors from original file for this specific file\n        original_errors = self._get_original_file_errors(xml_file)\n\n        # Compare with original (both are guaranteed to be sets here)\n        assert current_errors is not None\n        new_errors = current_errors - original_errors\n\n        if new_errors:\n            if verbose:\n                relative_path = xml_file.relative_to(unpacked_dir)\n                print(f\"FAILED - {relative_path}: {len(new_errors)} new error(s)\")\n                for error in list(new_errors)[:3]:\n                    truncated = error[:250] + \"...\" if len(error) > 250 else error\n                    print(f\"  - {truncated}\")\n            return False, new_errors\n        else:\n            # All errors existed in original\n            if verbose:\n                print(\n                    f\"PASSED - No new errors (original had {len(current_errors)} errors)\"\n                )\n            return True, set()\n\n    def validate_against_xsd(self):\n        \"\"\"Validate XML files against XSD schemas, showing only new errors compared to original.\"\"\"\n        new_errors = []\n        original_error_count = 0\n        valid_count = 0\n        skipped_count = 0\n\n        for xml_file in self.xml_files:\n            relative_path = str(xml_file.relative_to(self.unpacked_dir))\n            is_valid, new_file_errors = self.validate_file_against_xsd(\n                xml_file, verbose=False\n            )\n\n            if is_valid is None:\n                skipped_count += 1\n                continue\n            elif is_valid and not new_file_errors:\n                valid_count += 1\n                continue\n            elif is_valid:\n                # Had errors but all existed in original\n                original_error_count += 1\n                valid_count += 1\n                continue\n\n            # Has new errors\n            new_errors.append(f\"  {relative_path}: {len(new_file_errors)} new error(s)\")\n            for error in list(new_file_errors)[:3]:  # Show first 3 errors\n                new_errors.append(\n                    f\"    - {error[:250]}...\" if len(error) > 250 else f\"    - {error}\"\n                )\n\n        # Print summary\n        if self.verbose:\n            print(f\"Validated {len(self.xml_files)} files:\")\n            print(f\"  - Valid: {valid_count}\")\n            print(f\"  - Skipped (no schema): {skipped_count}\")\n            if original_error_count:\n                print(f\"  - With original errors (ignored): {original_error_count}\")\n            print(\n                f\"  - With NEW errors: {len(new_errors) > 0 and len([e for e in new_errors if not e.startswith('    ')]) or 0}\"\n            )\n\n        if new_errors:\n            print(\"\\nFAILED - Found NEW validation errors:\")\n            for error in new_errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"\\nPASSED - No new XSD validation errors introduced\")\n            return True\n\n    def _get_schema_path(self, xml_file):\n        \"\"\"Determine the appropriate schema path for an XML file.\"\"\"\n        # Check exact filename match\n        if xml_file.name in self.SCHEMA_MAPPINGS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.name]\n\n        # Check .rels files\n        if xml_file.suffix == \".rels\":\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\".rels\"]\n\n        # Check chart files\n        if \"charts/\" in str(xml_file) and xml_file.name.startswith(\"chart\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"chart\"]\n\n        # Check theme files\n        if \"theme/\" in str(xml_file) and xml_file.name.startswith(\"theme\"):\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[\"theme\"]\n\n        # Check if file is in a main content folder and use appropriate schema\n        if xml_file.parent.name in self.MAIN_CONTENT_FOLDERS:\n            return self.schemas_dir / self.SCHEMA_MAPPINGS[xml_file.parent.name]\n\n        return None\n\n    def _clean_ignorable_namespaces(self, xml_doc):\n        \"\"\"Remove attributes and elements not in allowed namespaces.\"\"\"\n        # Create a clean copy\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        # Remove attributes not in allowed namespaces\n        for elem in xml_copy.iter():\n            attrs_to_remove = []\n\n            for attr in elem.attrib:\n                # Check if attribute is from a namespace other than allowed ones\n                if \"{\" in attr:\n                    ns = attr.split(\"}\")[0][1:]\n                    if ns not in self.OOXML_NAMESPACES:\n                        attrs_to_remove.append(attr)\n\n            # Remove collected attributes\n            for attr in attrs_to_remove:\n                del elem.attrib[attr]\n\n        # Remove elements not in allowed namespaces\n        self._remove_ignorable_elements(xml_copy)\n\n        return lxml.etree.ElementTree(xml_copy)\n\n    def _remove_ignorable_elements(self, root):\n        \"\"\"Recursively remove all elements not in allowed namespaces.\"\"\"\n        elements_to_remove = []\n\n        # Find elements to remove\n        for elem in list(root):\n            # Skip non-element nodes (comments, processing instructions, etc.)\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n\n            tag_str = str(elem.tag)\n            if tag_str.startswith(\"{\"):\n                ns = tag_str.split(\"}\")[0][1:]\n                if ns not in self.OOXML_NAMESPACES:\n                    elements_to_remove.append(elem)\n                    continue\n\n            # Recursively clean child elements\n            self._remove_ignorable_elements(elem)\n\n        # Remove collected elements\n        for elem in elements_to_remove:\n            root.remove(elem)\n\n    def _preprocess_for_mc_ignorable(self, xml_doc):\n        \"\"\"Preprocess XML to handle mc:Ignorable attribute properly.\"\"\"\n        # Remove mc:Ignorable attributes before validation\n        root = xml_doc.getroot()\n\n        # Remove mc:Ignorable attribute from root\n        if f\"{{{self.MC_NAMESPACE}}}Ignorable\" in root.attrib:\n            del root.attrib[f\"{{{self.MC_NAMESPACE}}}Ignorable\"]\n\n        return xml_doc\n\n    def _validate_single_file_xsd(self, xml_file, base_path):\n        \"\"\"Validate a single XML file against XSD schema. Returns (is_valid, errors_set).\"\"\"\n        schema_path = self._get_schema_path(xml_file)\n        if not schema_path:\n            return None, None  # Skip file\n\n        try:\n            # Load schema\n            with open(schema_path, \"rb\") as xsd_file:\n                parser = lxml.etree.XMLParser()\n                xsd_doc = lxml.etree.parse(\n                    xsd_file, parser=parser, base_url=str(schema_path)\n                )\n                schema = lxml.etree.XMLSchema(xsd_doc)\n\n            # Load and preprocess XML\n            with open(xml_file, \"r\") as f:\n                xml_doc = lxml.etree.parse(f)\n\n            xml_doc, _ = self._remove_template_tags_from_text_nodes(xml_doc)\n            xml_doc = self._preprocess_for_mc_ignorable(xml_doc)\n\n            # Clean ignorable namespaces if needed\n            relative_path = xml_file.relative_to(base_path)\n            if (\n                relative_path.parts\n                and relative_path.parts[0] in self.MAIN_CONTENT_FOLDERS\n            ):\n                xml_doc = self._clean_ignorable_namespaces(xml_doc)\n\n            # Validate\n            if schema.validate(xml_doc):\n                return True, set()\n            else:\n                errors = set()\n                for error in schema.error_log:\n                    # Store normalized error message (without line numbers for comparison)\n                    errors.add(error.message)\n                return False, errors\n\n        except Exception as e:\n            return False, {str(e)}\n\n    def _get_original_file_errors(self, xml_file):\n        \"\"\"Get XSD validation errors from a single file in the original document.\n\n        Args:\n            xml_file: Path to the XML file in unpacked_dir to check\n\n        Returns:\n            set: Set of error messages from the original file\n        \"\"\"\n        import tempfile\n        import zipfile\n\n        # Resolve both paths to handle symlinks (e.g., /var vs /private/var on macOS)\n        xml_file = Path(xml_file).resolve()\n        unpacked_dir = self.unpacked_dir.resolve()\n        relative_path = xml_file.relative_to(unpacked_dir)\n\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            # Extract original file\n            with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                zip_ref.extractall(temp_path)\n\n            # Find corresponding file in original\n            original_xml_file = temp_path / relative_path\n\n            if not original_xml_file.exists():\n                # File didn't exist in original, so no original errors\n                return set()\n\n            # Validate the specific file in original\n            is_valid, errors = self._validate_single_file_xsd(\n                original_xml_file, temp_path\n            )\n            return errors if errors else set()\n\n    def _remove_template_tags_from_text_nodes(self, xml_doc):\n        \"\"\"Remove template tags from XML text nodes and collect warnings.\n\n        Template tags follow the pattern {{ ... }} and are used as placeholders\n        for content replacement. They should be removed from text content before\n        XSD validation while preserving XML structure.\n\n        Returns:\n            tuple: (cleaned_xml_doc, warnings_list)\n        \"\"\"\n        warnings = []\n        template_pattern = re.compile(r\"\\{\\{[^}]*\\}\\}\")\n\n        # Create a copy of the document to avoid modifying the original\n        xml_string = lxml.etree.tostring(xml_doc, encoding=\"unicode\")\n        xml_copy = lxml.etree.fromstring(xml_string)\n\n        def process_text_content(text, content_type):\n            if not text:\n                return text\n            matches = list(template_pattern.finditer(text))\n            if matches:\n                for match in matches:\n                    warnings.append(\n                        f\"Found template tag in {content_type}: {match.group()}\"\n                    )\n                return template_pattern.sub(\"\", text)\n            return text\n\n        # Process all text nodes in the document\n        for elem in xml_copy.iter():\n            # Skip processing if this is a w:t element\n            if not hasattr(elem, \"tag\") or callable(elem.tag):\n                continue\n            tag_str = str(elem.tag)\n            if tag_str.endswith(\"}t\") or tag_str == \"t\":\n                continue\n\n            elem.text = process_text_content(elem.text, \"text content\")\n            elem.tail = process_text_content(elem.tail, \"tail content\")\n\n        return lxml.etree.ElementTree(xml_copy), warnings\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validation/docx.py",
    "content": "\"\"\"\nValidator for Word document XML files against XSD schemas.\n\"\"\"\n\nimport re\nimport tempfile\nimport zipfile\n\nimport lxml.etree\n\nfrom .base import BaseSchemaValidator\n\n\nclass DOCXSchemaValidator(BaseSchemaValidator):\n    \"\"\"Validator for Word document XML files against XSD schemas.\"\"\"\n\n    # Word-specific namespace\n    WORD_2006_NAMESPACE = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\n    # Word-specific element to relationship type mappings\n    # Start with empty mapping - add specific cases as we discover them\n    ELEMENT_RELATIONSHIP_TYPES = {}\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        # Test 0: XML well-formedness\n        if not self.validate_xml():\n            return False\n\n        # Test 1: Namespace declarations\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        # Test 2: Unique IDs\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        # Test 3: Relationship and file reference validation\n        if not self.validate_file_references():\n            all_valid = False\n\n        # Test 4: Content type declarations\n        if not self.validate_content_types():\n            all_valid = False\n\n        # Test 5: XSD schema validation\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        # Test 6: Whitespace preservation\n        if not self.validate_whitespace_preservation():\n            all_valid = False\n\n        # Test 7: Deletion validation\n        if not self.validate_deletions():\n            all_valid = False\n\n        # Test 8: Insertion validation\n        if not self.validate_insertions():\n            all_valid = False\n\n        # Test 9: Relationship ID reference validation\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        # Count and compare paragraphs\n        self.compare_paragraph_counts()\n\n        return all_valid\n\n    def validate_whitespace_preservation(self):\n        \"\"\"\n        Validate that w:t elements with whitespace have xml:space='preserve'.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all w:t elements\n                for elem in root.iter(f\"{{{self.WORD_2006_NAMESPACE}}}t\"):\n                    if elem.text:\n                        text = elem.text\n                        # Check if text starts or ends with whitespace\n                        if re.match(r\"^\\s.*\", text) or re.match(r\".*\\s$\", text):\n                            # Check if xml:space=\"preserve\" attribute exists\n                            xml_space_attr = f\"{{{self.XML_NAMESPACE}}}space\"\n                            if (\n                                xml_space_attr not in elem.attrib\n                                or elem.attrib[xml_space_attr] != \"preserve\"\n                            ):\n                                # Show a preview of the text\n                                text_preview = (\n                                    repr(text)[:50] + \"...\"\n                                    if len(repr(text)) > 50\n                                    else repr(text)\n                                )\n                                errors.append(\n                                    f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                    f\"Line {elem.sourceline}: w:t element with whitespace missing xml:space='preserve': {text_preview}\"\n                                )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} whitespace preservation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All whitespace is properly preserved\")\n            return True\n\n    def validate_deletions(self):\n        \"\"\"\n        Validate that w:t elements are not within w:del elements.\n        For some reason, XSD validation does not catch this, so we do it manually.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Find all w:t elements that are descendants of w:del elements\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n                xpath_expression = \".//w:del//w:t\"\n                problematic_t_elements = root.xpath(\n                    xpath_expression, namespaces=namespaces\n                )\n                for t_elem in problematic_t_elements:\n                    if t_elem.text:\n                        # Show a preview of the text\n                        text_preview = (\n                            repr(t_elem.text)[:50] + \"...\"\n                            if len(repr(t_elem.text)) > 50\n                            else repr(t_elem.text)\n                        )\n                        errors.append(\n                            f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {t_elem.sourceline}: <w:t> found within <w:del>: {text_preview}\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} deletion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:t elements found within w:del elements\")\n            return True\n\n    def count_paragraphs_in_unpacked(self):\n        \"\"\"Count the number of paragraphs in the unpacked document.\"\"\"\n        count = 0\n\n        for xml_file in self.xml_files:\n            # Only check document.xml files\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                # Count all w:p elements\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n            except Exception as e:\n                print(f\"Error counting paragraphs in unpacked document: {e}\")\n\n        return count\n\n    def count_paragraphs_in_original(self):\n        \"\"\"Count the number of paragraphs in the original docx file.\"\"\"\n        count = 0\n\n        try:\n            # Create temporary directory to unpack original\n            with tempfile.TemporaryDirectory() as temp_dir:\n                # Unpack original docx\n                with zipfile.ZipFile(self.original_file, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_dir)\n\n                # Parse document.xml\n                doc_xml_path = temp_dir + \"/word/document.xml\"\n                root = lxml.etree.parse(doc_xml_path).getroot()\n\n                # Count all w:p elements\n                paragraphs = root.findall(f\".//{{{self.WORD_2006_NAMESPACE}}}p\")\n                count = len(paragraphs)\n\n        except Exception as e:\n            print(f\"Error counting paragraphs in original document: {e}\")\n\n        return count\n\n    def validate_insertions(self):\n        \"\"\"\n        Validate that w:delText elements are not within w:ins elements.\n        w:delText is only allowed in w:ins if nested within a w:del.\n        \"\"\"\n        errors = []\n\n        for xml_file in self.xml_files:\n            if xml_file.name != \"document.xml\":\n                continue\n\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n                namespaces = {\"w\": self.WORD_2006_NAMESPACE}\n\n                # Find w:delText in w:ins that are NOT within w:del\n                invalid_elements = root.xpath(\n                    \".//w:ins//w:delText[not(ancestor::w:del)]\",\n                    namespaces=namespaces\n                )\n\n                for elem in invalid_elements:\n                    text_preview = (\n                        repr(elem.text or \"\")[:50] + \"...\"\n                        if len(repr(elem.text or \"\")) > 50\n                        else repr(elem.text or \"\")\n                    )\n                    errors.append(\n                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                        f\"Line {elem.sourceline}: <w:delText> within <w:ins>: {text_preview}\"\n                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} insertion validation violations:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - No w:delText elements within w:ins elements\")\n            return True\n\n    def compare_paragraph_counts(self):\n        \"\"\"Compare paragraph counts between original and new document.\"\"\"\n        original_count = self.count_paragraphs_in_original()\n        new_count = self.count_paragraphs_in_unpacked()\n\n        diff = new_count - original_count\n        diff_str = f\"+{diff}\" if diff > 0 else str(diff)\n        print(f\"\\nParagraphs: {original_count} → {new_count} ({diff_str})\")\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validation/pptx.py",
    "content": "\"\"\"\nValidator for PowerPoint presentation XML files against XSD schemas.\n\"\"\"\n\nimport re\n\nfrom .base import BaseSchemaValidator\n\n\nclass PPTXSchemaValidator(BaseSchemaValidator):\n    \"\"\"Validator for PowerPoint presentation XML files against XSD schemas.\"\"\"\n\n    # PowerPoint presentation namespace\n    PRESENTATIONML_NAMESPACE = (\n        \"http://schemas.openxmlformats.org/presentationml/2006/main\"\n    )\n\n    # PowerPoint-specific element to relationship type mappings\n    ELEMENT_RELATIONSHIP_TYPES = {\n        \"sldid\": \"slide\",\n        \"sldmasterid\": \"slidemaster\",\n        \"notesmasterid\": \"notesmaster\",\n        \"sldlayoutid\": \"slidelayout\",\n        \"themeid\": \"theme\",\n        \"tablestyleid\": \"tablestyles\",\n    }\n\n    def validate(self):\n        \"\"\"Run all validation checks and return True if all pass.\"\"\"\n        # Test 0: XML well-formedness\n        if not self.validate_xml():\n            return False\n\n        # Test 1: Namespace declarations\n        all_valid = True\n        if not self.validate_namespaces():\n            all_valid = False\n\n        # Test 2: Unique IDs\n        if not self.validate_unique_ids():\n            all_valid = False\n\n        # Test 3: UUID ID validation\n        if not self.validate_uuid_ids():\n            all_valid = False\n\n        # Test 4: Relationship and file reference validation\n        if not self.validate_file_references():\n            all_valid = False\n\n        # Test 5: Slide layout ID validation\n        if not self.validate_slide_layout_ids():\n            all_valid = False\n\n        # Test 6: Content type declarations\n        if not self.validate_content_types():\n            all_valid = False\n\n        # Test 7: XSD schema validation\n        if not self.validate_against_xsd():\n            all_valid = False\n\n        # Test 8: Notes slide reference validation\n        if not self.validate_notes_slide_references():\n            all_valid = False\n\n        # Test 9: Relationship ID reference validation\n        if not self.validate_all_relationship_ids():\n            all_valid = False\n\n        # Test 10: Duplicate slide layout references validation\n        if not self.validate_no_duplicate_slide_layouts():\n            all_valid = False\n\n        return all_valid\n\n    def validate_uuid_ids(self):\n        \"\"\"Validate that ID attributes that look like UUIDs contain only hex values.\"\"\"\n        import lxml.etree\n\n        errors = []\n        # UUID pattern: 8-4-4-4-12 hex digits with optional braces/hyphens\n        uuid_pattern = re.compile(\n            r\"^[\\{\\(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[\\}\\)]?$\"\n        )\n\n        for xml_file in self.xml_files:\n            try:\n                root = lxml.etree.parse(str(xml_file)).getroot()\n\n                # Check all elements for ID attributes\n                for elem in root.iter():\n                    for attr, value in elem.attrib.items():\n                        # Check if this is an ID attribute\n                        attr_name = attr.split(\"}\")[-1].lower()\n                        if attr_name == \"id\" or attr_name.endswith(\"id\"):\n                            # Check if value looks like a UUID (has the right length and pattern structure)\n                            if self._looks_like_uuid(value):\n                                # Validate that it contains only hex characters in the right positions\n                                if not uuid_pattern.match(value):\n                                    errors.append(\n                                        f\"  {xml_file.relative_to(self.unpacked_dir)}: \"\n                                        f\"Line {elem.sourceline}: ID '{value}' appears to be a UUID but contains invalid hex characters\"\n                                    )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {xml_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} UUID ID validation errors:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All UUID-like IDs contain valid hex values\")\n            return True\n\n    def _looks_like_uuid(self, value):\n        \"\"\"Check if a value has the general structure of a UUID.\"\"\"\n        # Remove common UUID delimiters\n        clean_value = value.strip(\"{}()\").replace(\"-\", \"\")\n        # Check if it's 32 hex-like characters (could include invalid hex chars)\n        return len(clean_value) == 32 and all(c.isalnum() for c in clean_value)\n\n    def validate_slide_layout_ids(self):\n        \"\"\"Validate that sldLayoutId elements in slide masters reference valid slide layouts.\"\"\"\n        import lxml.etree\n\n        errors = []\n\n        # Find all slide master files\n        slide_masters = list(self.unpacked_dir.glob(\"ppt/slideMasters/*.xml\"))\n\n        if not slide_masters:\n            if self.verbose:\n                print(\"PASSED - No slide masters found\")\n            return True\n\n        for slide_master in slide_masters:\n            try:\n                # Parse the slide master file\n                root = lxml.etree.parse(str(slide_master)).getroot()\n\n                # Find the corresponding _rels file for this slide master\n                rels_file = slide_master.parent / \"_rels\" / f\"{slide_master.name}.rels\"\n\n                if not rels_file.exists():\n                    errors.append(\n                        f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                        f\"Missing relationships file: {rels_file.relative_to(self.unpacked_dir)}\"\n                    )\n                    continue\n\n                # Parse the relationships file\n                rels_root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Build a set of valid relationship IDs that point to slide layouts\n                valid_layout_rids = set()\n                for rel in rels_root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"slideLayout\" in rel_type:\n                        valid_layout_rids.add(rel.get(\"Id\"))\n\n                # Find all sldLayoutId elements in the slide master\n                for sld_layout_id in root.findall(\n                    f\".//{{{self.PRESENTATIONML_NAMESPACE}}}sldLayoutId\"\n                ):\n                    r_id = sld_layout_id.get(\n                        f\"{{{self.OFFICE_RELATIONSHIPS_NAMESPACE}}}id\"\n                    )\n                    layout_id = sld_layout_id.get(\"id\")\n\n                    if r_id and r_id not in valid_layout_rids:\n                        errors.append(\n                            f\"  {slide_master.relative_to(self.unpacked_dir)}: \"\n                            f\"Line {sld_layout_id.sourceline}: sldLayoutId with id='{layout_id}' \"\n                            f\"references r:id='{r_id}' which is not found in slide layout relationships\"\n                        )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {slide_master.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(f\"FAILED - Found {len(errors)} slide layout ID validation errors:\")\n            for error in errors:\n                print(error)\n            print(\n                \"Remove invalid references or add missing slide layouts to the relationships file.\"\n            )\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slide layout IDs reference valid slide layouts\")\n            return True\n\n    def validate_no_duplicate_slide_layouts(self):\n        \"\"\"Validate that each slide has exactly one slideLayout reference.\"\"\"\n        import lxml.etree\n\n        errors = []\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        for rels_file in slide_rels_files:\n            try:\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Find all slideLayout relationships\n                layout_rels = [\n                    rel\n                    for rel in root.findall(\n                        f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                    )\n                    if \"slideLayout\" in rel.get(\"Type\", \"\")\n                ]\n\n                if len(layout_rels) > 1:\n                    errors.append(\n                        f\"  {rels_file.relative_to(self.unpacked_dir)}: has {len(layout_rels)} slideLayout references\"\n                    )\n\n            except Exception as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        if errors:\n            print(\"FAILED - Found slides with duplicate slideLayout references:\")\n            for error in errors:\n                print(error)\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All slides have exactly one slideLayout reference\")\n            return True\n\n    def validate_notes_slide_references(self):\n        \"\"\"Validate that each notesSlide file is referenced by only one slide.\"\"\"\n        import lxml.etree\n\n        errors = []\n        notes_slide_references = {}  # Track which slides reference each notesSlide\n\n        # Find all slide relationship files\n        slide_rels_files = list(self.unpacked_dir.glob(\"ppt/slides/_rels/*.xml.rels\"))\n\n        if not slide_rels_files:\n            if self.verbose:\n                print(\"PASSED - No slide relationship files found\")\n            return True\n\n        for rels_file in slide_rels_files:\n            try:\n                # Parse the relationships file\n                root = lxml.etree.parse(str(rels_file)).getroot()\n\n                # Find all notesSlide relationships\n                for rel in root.findall(\n                    f\".//{{{self.PACKAGE_RELATIONSHIPS_NAMESPACE}}}Relationship\"\n                ):\n                    rel_type = rel.get(\"Type\", \"\")\n                    if \"notesSlide\" in rel_type:\n                        target = rel.get(\"Target\", \"\")\n                        if target:\n                            # Normalize the target path to handle relative paths\n                            normalized_target = target.replace(\"../\", \"\")\n\n                            # Track which slide references this notesSlide\n                            slide_name = rels_file.stem.replace(\n                                \".xml\", \"\"\n                            )  # e.g., \"slide1\"\n\n                            if normalized_target not in notes_slide_references:\n                                notes_slide_references[normalized_target] = []\n                            notes_slide_references[normalized_target].append(\n                                (slide_name, rels_file)\n                            )\n\n            except (lxml.etree.XMLSyntaxError, Exception) as e:\n                errors.append(\n                    f\"  {rels_file.relative_to(self.unpacked_dir)}: Error: {e}\"\n                )\n\n        # Check for duplicate references\n        for target, references in notes_slide_references.items():\n            if len(references) > 1:\n                slide_names = [ref[0] for ref in references]\n                errors.append(\n                    f\"  Notes slide '{target}' is referenced by multiple slides: {', '.join(slide_names)}\"\n                )\n                for slide_name, rels_file in references:\n                    errors.append(f\"    - {rels_file.relative_to(self.unpacked_dir)}\")\n\n        if errors:\n            print(\n                f\"FAILED - Found {len([e for e in errors if not e.startswith('    ')])} notes slide reference validation errors:\"\n            )\n            for error in errors:\n                print(error)\n            print(\"Each slide may optionally have its own slide file.\")\n            return False\n        else:\n            if self.verbose:\n                print(\"PASSED - All notes slide references are unique\")\n            return True\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/pptx/ooxml/scripts/validation/redlining.py",
    "content": "\"\"\"\nValidator for tracked changes in Word documents.\n\"\"\"\n\nimport subprocess\nimport tempfile\nimport zipfile\nfrom pathlib import Path\n\n\nclass RedliningValidator:\n    \"\"\"Validator for tracked changes in Word documents.\"\"\"\n\n    def __init__(self, unpacked_dir, original_docx, verbose=False):\n        self.unpacked_dir = Path(unpacked_dir)\n        self.original_docx = Path(original_docx)\n        self.verbose = verbose\n        self.namespaces = {\n            \"w\": \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n        }\n\n    def validate(self):\n        \"\"\"Main validation method that returns True if valid, False otherwise.\"\"\"\n        # Verify unpacked directory exists and has correct structure\n        modified_file = self.unpacked_dir / \"word\" / \"document.xml\"\n        if not modified_file.exists():\n            print(f\"FAILED - Modified document.xml not found at {modified_file}\")\n            return False\n\n        # First, check if there are any tracked changes by Claude to validate\n        try:\n            import xml.etree.ElementTree as ET\n\n            tree = ET.parse(modified_file)\n            root = tree.getroot()\n\n            # Check for w:del or w:ins tags authored by Claude\n            del_elements = root.findall(\".//w:del\", self.namespaces)\n            ins_elements = root.findall(\".//w:ins\", self.namespaces)\n\n            # Filter to only include changes by Claude\n            claude_del_elements = [\n                elem\n                for elem in del_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == \"Claude\"\n            ]\n            claude_ins_elements = [\n                elem\n                for elem in ins_elements\n                if elem.get(f\"{{{self.namespaces['w']}}}author\") == \"Claude\"\n            ]\n\n            # Redlining validation is only needed if tracked changes by Claude have been used.\n            if not claude_del_elements and not claude_ins_elements:\n                if self.verbose:\n                    print(\"PASSED - No tracked changes by Claude found.\")\n                return True\n\n        except Exception:\n            # If we can't parse the XML, continue with full validation\n            pass\n\n        # Create temporary directory for unpacking original docx\n        with tempfile.TemporaryDirectory() as temp_dir:\n            temp_path = Path(temp_dir)\n\n            # Unpack original docx\n            try:\n                with zipfile.ZipFile(self.original_docx, \"r\") as zip_ref:\n                    zip_ref.extractall(temp_path)\n            except Exception as e:\n                print(f\"FAILED - Error unpacking original docx: {e}\")\n                return False\n\n            original_file = temp_path / \"word\" / \"document.xml\"\n            if not original_file.exists():\n                print(\n                    f\"FAILED - Original document.xml not found in {self.original_docx}\"\n                )\n                return False\n\n            # Parse both XML files using xml.etree.ElementTree for redlining validation\n            try:\n                import xml.etree.ElementTree as ET\n\n                modified_tree = ET.parse(modified_file)\n                modified_root = modified_tree.getroot()\n                original_tree = ET.parse(original_file)\n                original_root = original_tree.getroot()\n            except ET.ParseError as e:\n                print(f\"FAILED - Error parsing XML files: {e}\")\n                return False\n\n            # Remove Claude's tracked changes from both documents\n            self._remove_claude_tracked_changes(original_root)\n            self._remove_claude_tracked_changes(modified_root)\n\n            # Extract and compare text content\n            modified_text = self._extract_text_content(modified_root)\n            original_text = self._extract_text_content(original_root)\n\n            if modified_text != original_text:\n                # Show detailed character-level differences for each paragraph\n                error_message = self._generate_detailed_diff(\n                    original_text, modified_text\n                )\n                print(error_message)\n                return False\n\n            if self.verbose:\n                print(\"PASSED - All changes by Claude are properly tracked\")\n            return True\n\n    def _generate_detailed_diff(self, original_text, modified_text):\n        \"\"\"Generate detailed word-level differences using git word diff.\"\"\"\n        error_parts = [\n            \"FAILED - Document text doesn't match after removing Claude's tracked changes\",\n            \"\",\n            \"Likely causes:\",\n            \"  1. Modified text inside another author's <w:ins> or <w:del> tags\",\n            \"  2. Made edits without proper tracked changes\",\n            \"  3. Didn't nest <w:del> inside <w:ins> when deleting another's insertion\",\n            \"\",\n            \"For pre-redlined documents, use correct patterns:\",\n            \"  - To reject another's INSERTION: Nest <w:del> inside their <w:ins>\",\n            \"  - To restore another's DELETION: Add new <w:ins> AFTER their <w:del>\",\n            \"\",\n        ]\n\n        # Show git word diff\n        git_diff = self._get_git_word_diff(original_text, modified_text)\n        if git_diff:\n            error_parts.extend([\"Differences:\", \"============\", git_diff])\n        else:\n            error_parts.append(\"Unable to generate word diff (git not available)\")\n\n        return \"\\n\".join(error_parts)\n\n    def _get_git_word_diff(self, original_text, modified_text):\n        \"\"\"Generate word diff using git with character-level precision.\"\"\"\n        try:\n            with tempfile.TemporaryDirectory() as temp_dir:\n                temp_path = Path(temp_dir)\n\n                # Create two files\n                original_file = temp_path / \"original.txt\"\n                modified_file = temp_path / \"modified.txt\"\n\n                original_file.write_text(original_text, encoding=\"utf-8\")\n                modified_file.write_text(modified_text, encoding=\"utf-8\")\n\n                # Try character-level diff first for precise differences\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"--word-diff-regex=.\",  # Character-by-character diff\n                        \"-U0\",  # Zero lines of context - show only changed lines\n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    # Clean up the output - remove git diff header lines\n                    lines = result.stdout.split(\"\\n\")\n                    # Skip the header lines (diff --git, index, +++, ---, @@)\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n\n                    if content_lines:\n                        return \"\\n\".join(content_lines)\n\n                # Fallback to word-level diff if character-level is too verbose\n                result = subprocess.run(\n                    [\n                        \"git\",\n                        \"diff\",\n                        \"--word-diff=plain\",\n                        \"-U0\",  # Zero lines of context\n                        \"--no-index\",\n                        str(original_file),\n                        str(modified_file),\n                    ],\n                    capture_output=True,\n                    text=True,\n                )\n\n                if result.stdout.strip():\n                    lines = result.stdout.split(\"\\n\")\n                    content_lines = []\n                    in_content = False\n                    for line in lines:\n                        if line.startswith(\"@@\"):\n                            in_content = True\n                            continue\n                        if in_content and line.strip():\n                            content_lines.append(line)\n                    return \"\\n\".join(content_lines)\n\n        except (subprocess.CalledProcessError, FileNotFoundError, Exception):\n            # Git not available or other error, return None to use fallback\n            pass\n\n        return None\n\n    def _remove_claude_tracked_changes(self, root):\n        \"\"\"Remove tracked changes authored by Claude from the XML root.\"\"\"\n        ins_tag = f\"{{{self.namespaces['w']}}}ins\"\n        del_tag = f\"{{{self.namespaces['w']}}}del\"\n        author_attr = f\"{{{self.namespaces['w']}}}author\"\n\n        # Remove w:ins elements\n        for parent in root.iter():\n            to_remove = []\n            for child in parent:\n                if child.tag == ins_tag and child.get(author_attr) == \"Claude\":\n                    to_remove.append(child)\n            for elem in to_remove:\n                parent.remove(elem)\n\n        # Unwrap content in w:del elements where author is \"Claude\"\n        deltext_tag = f\"{{{self.namespaces['w']}}}delText\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        for parent in root.iter():\n            to_process = []\n            for child in parent:\n                if child.tag == del_tag and child.get(author_attr) == \"Claude\":\n                    to_process.append((child, list(parent).index(child)))\n\n            # Process in reverse order to maintain indices\n            for del_elem, del_index in reversed(to_process):\n                # Convert w:delText to w:t before moving\n                for elem in del_elem.iter():\n                    if elem.tag == deltext_tag:\n                        elem.tag = t_tag\n\n                # Move all children of w:del to its parent before removing w:del\n                for child in reversed(list(del_elem)):\n                    parent.insert(del_index, child)\n                parent.remove(del_elem)\n\n    def _extract_text_content(self, root):\n        \"\"\"Extract text content from Word XML, preserving paragraph structure.\n\n        Empty paragraphs are skipped to avoid false positives when tracked\n        insertions add only structural elements without text content.\n        \"\"\"\n        p_tag = f\"{{{self.namespaces['w']}}}p\"\n        t_tag = f\"{{{self.namespaces['w']}}}t\"\n\n        paragraphs = []\n        for p_elem in root.findall(f\".//{p_tag}\"):\n            # Get all text elements within this paragraph\n            text_parts = []\n            for t_elem in p_elem.findall(f\".//{t_tag}\"):\n                if t_elem.text:\n                    text_parts.append(t_elem.text)\n            paragraph_text = \"\".join(text_parts)\n            # Skip empty paragraphs - they don't affect content validation\n            if paragraph_text:\n                paragraphs.append(paragraph_text)\n\n        return \"\\n\".join(paragraphs)\n\n\nif __name__ == \"__main__\":\n    raise RuntimeError(\"This module should not be run directly.\")\n"
  },
  {
    "path": "document-skills/pptx/ooxml.md",
    "content": "# Office Open XML Technical Reference for PowerPoint\n\n**Important: Read this entire document before starting.** Critical XML schema rules and formatting requirements are covered throughout. Incorrect implementation can create invalid PPTX files that PowerPoint cannot open.\n\n## Technical Guidelines\n\n### Schema Compliance\n- **Element ordering in `<p:txBody>`**: `<a:bodyPr>`, `<a:lstStyle>`, `<a:p>`\n- **Whitespace**: Add `xml:space='preserve'` to `<a:t>` elements with leading/trailing spaces\n- **Unicode**: Escape characters in ASCII content: `\"` becomes `&#8220;`\n- **Images**: Add to `ppt/media/`, reference in slide XML, set dimensions to fit slide bounds\n- **Relationships**: Update `ppt/slides/_rels/slideN.xml.rels` for each slide's resources\n- **Dirty attribute**: Add `dirty=\"0\"` to `<a:rPr>` and `<a:endParaRPr>` elements to indicate clean state\n\n## Presentation Structure\n\n### Basic Slide Structure\n```xml\n<!-- ppt/slides/slide1.xml -->\n<p:sld>\n  <p:cSld>\n    <p:spTree>\n      <p:nvGrpSpPr>...</p:nvGrpSpPr>\n      <p:grpSpPr>...</p:grpSpPr>\n      <!-- Shapes go here -->\n    </p:spTree>\n  </p:cSld>\n</p:sld>\n```\n\n### Text Box / Shape with Text\n```xml\n<p:sp>\n  <p:nvSpPr>\n    <p:cNvPr id=\"2\" name=\"Title\"/>\n    <p:cNvSpPr>\n      <a:spLocks noGrp=\"1\"/>\n    </p:cNvSpPr>\n    <p:nvPr>\n      <p:ph type=\"ctrTitle\"/>\n    </p:nvPr>\n  </p:nvSpPr>\n  <p:spPr>\n    <a:xfrm>\n      <a:off x=\"838200\" y=\"365125\"/>\n      <a:ext cx=\"7772400\" cy=\"1470025\"/>\n    </a:xfrm>\n  </p:spPr>\n  <p:txBody>\n    <a:bodyPr/>\n    <a:lstStyle/>\n    <a:p>\n      <a:r>\n        <a:t>Slide Title</a:t>\n      </a:r>\n    </a:p>\n  </p:txBody>\n</p:sp>\n```\n\n### Text Formatting\n```xml\n<!-- Bold -->\n<a:r>\n  <a:rPr b=\"1\"/>\n  <a:t>Bold Text</a:t>\n</a:r>\n\n<!-- Italic -->\n<a:r>\n  <a:rPr i=\"1\"/>\n  <a:t>Italic Text</a:t>\n</a:r>\n\n<!-- Underline -->\n<a:r>\n  <a:rPr u=\"sng\"/>\n  <a:t>Underlined</a:t>\n</a:r>\n\n<!-- Highlight -->\n<a:r>\n  <a:rPr>\n    <a:highlight>\n      <a:srgbClr val=\"FFFF00\"/>\n    </a:highlight>\n  </a:rPr>\n  <a:t>Highlighted Text</a:t>\n</a:r>\n\n<!-- Font and Size -->\n<a:r>\n  <a:rPr sz=\"2400\" typeface=\"Arial\">\n    <a:solidFill>\n      <a:srgbClr val=\"FF0000\"/>\n    </a:solidFill>\n  </a:rPr>\n  <a:t>Colored Arial 24pt</a:t>\n</a:r>\n\n<!-- Complete formatting example -->\n<a:r>\n  <a:rPr lang=\"en-US\" sz=\"1400\" b=\"1\" dirty=\"0\">\n    <a:solidFill>\n      <a:srgbClr val=\"FAFAFA\"/>\n    </a:solidFill>\n  </a:rPr>\n  <a:t>Formatted text</a:t>\n</a:r>\n```\n\n### Lists\n```xml\n<!-- Bullet list -->\n<a:p>\n  <a:pPr lvl=\"0\">\n    <a:buChar char=\"•\"/>\n  </a:pPr>\n  <a:r>\n    <a:t>First bullet point</a:t>\n  </a:r>\n</a:p>\n\n<!-- Numbered list -->\n<a:p>\n  <a:pPr lvl=\"0\">\n    <a:buAutoNum type=\"arabicPeriod\"/>\n  </a:pPr>\n  <a:r>\n    <a:t>First numbered item</a:t>\n  </a:r>\n</a:p>\n\n<!-- Second level indent -->\n<a:p>\n  <a:pPr lvl=\"1\">\n    <a:buChar char=\"•\"/>\n  </a:pPr>\n  <a:r>\n    <a:t>Indented bullet</a:t>\n  </a:r>\n</a:p>\n```\n\n### Shapes\n```xml\n<!-- Rectangle -->\n<p:sp>\n  <p:nvSpPr>\n    <p:cNvPr id=\"3\" name=\"Rectangle\"/>\n    <p:cNvSpPr/>\n    <p:nvPr/>\n  </p:nvSpPr>\n  <p:spPr>\n    <a:xfrm>\n      <a:off x=\"1000000\" y=\"1000000\"/>\n      <a:ext cx=\"3000000\" cy=\"2000000\"/>\n    </a:xfrm>\n    <a:prstGeom prst=\"rect\">\n      <a:avLst/>\n    </a:prstGeom>\n    <a:solidFill>\n      <a:srgbClr val=\"FF0000\"/>\n    </a:solidFill>\n    <a:ln w=\"25400\">\n      <a:solidFill>\n        <a:srgbClr val=\"000000\"/>\n      </a:solidFill>\n    </a:ln>\n  </p:spPr>\n</p:sp>\n\n<!-- Rounded Rectangle -->\n<p:sp>\n  <p:spPr>\n    <a:prstGeom prst=\"roundRect\">\n      <a:avLst/>\n    </a:prstGeom>\n  </p:spPr>\n</p:sp>\n\n<!-- Circle/Ellipse -->\n<p:sp>\n  <p:spPr>\n    <a:prstGeom prst=\"ellipse\">\n      <a:avLst/>\n    </a:prstGeom>\n  </p:spPr>\n</p:sp>\n```\n\n### Images\n```xml\n<p:pic>\n  <p:nvPicPr>\n    <p:cNvPr id=\"4\" name=\"Picture\">\n      <a:hlinkClick r:id=\"\" action=\"ppaction://media\"/>\n    </p:cNvPr>\n    <p:cNvPicPr>\n      <a:picLocks noChangeAspect=\"1\"/>\n    </p:cNvPicPr>\n    <p:nvPr/>\n  </p:nvPicPr>\n  <p:blipFill>\n    <a:blip r:embed=\"rId2\"/>\n    <a:stretch>\n      <a:fillRect/>\n    </a:stretch>\n  </p:blipFill>\n  <p:spPr>\n    <a:xfrm>\n      <a:off x=\"1000000\" y=\"1000000\"/>\n      <a:ext cx=\"3000000\" cy=\"2000000\"/>\n    </a:xfrm>\n    <a:prstGeom prst=\"rect\">\n      <a:avLst/>\n    </a:prstGeom>\n  </p:spPr>\n</p:pic>\n```\n\n### Tables\n```xml\n<p:graphicFrame>\n  <p:nvGraphicFramePr>\n    <p:cNvPr id=\"5\" name=\"Table\"/>\n    <p:cNvGraphicFramePr>\n      <a:graphicFrameLocks noGrp=\"1\"/>\n    </p:cNvGraphicFramePr>\n    <p:nvPr/>\n  </p:nvGraphicFramePr>\n  <p:xfrm>\n    <a:off x=\"1000000\" y=\"1000000\"/>\n    <a:ext cx=\"6000000\" cy=\"2000000\"/>\n  </p:xfrm>\n  <a:graphic>\n    <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/table\">\n      <a:tbl>\n        <a:tblGrid>\n          <a:gridCol w=\"3000000\"/>\n          <a:gridCol w=\"3000000\"/>\n        </a:tblGrid>\n        <a:tr h=\"500000\">\n          <a:tc>\n            <a:txBody>\n              <a:bodyPr/>\n              <a:lstStyle/>\n              <a:p>\n                <a:r>\n                  <a:t>Cell 1</a:t>\n                </a:r>\n              </a:p>\n            </a:txBody>\n          </a:tc>\n          <a:tc>\n            <a:txBody>\n              <a:bodyPr/>\n              <a:lstStyle/>\n              <a:p>\n                <a:r>\n                  <a:t>Cell 2</a:t>\n                </a:r>\n              </a:p>\n            </a:txBody>\n          </a:tc>\n        </a:tr>\n      </a:tbl>\n    </a:graphicData>\n  </a:graphic>\n</p:graphicFrame>\n```\n\n### Slide Layouts\n\n```xml\n<!-- Title Slide Layout -->\n<p:sp>\n  <p:nvSpPr>\n    <p:nvPr>\n      <p:ph type=\"ctrTitle\"/>\n    </p:nvPr>\n  </p:nvSpPr>\n  <!-- Title content -->\n</p:sp>\n\n<p:sp>\n  <p:nvSpPr>\n    <p:nvPr>\n      <p:ph type=\"subTitle\" idx=\"1\"/>\n    </p:nvPr>\n  </p:nvSpPr>\n  <!-- Subtitle content -->\n</p:sp>\n\n<!-- Content Slide Layout -->\n<p:sp>\n  <p:nvSpPr>\n    <p:nvPr>\n      <p:ph type=\"title\"/>\n    </p:nvPr>\n  </p:nvSpPr>\n  <!-- Slide title -->\n</p:sp>\n\n<p:sp>\n  <p:nvSpPr>\n    <p:nvPr>\n      <p:ph type=\"body\" idx=\"1\"/>\n    </p:nvPr>\n  </p:nvSpPr>\n  <!-- Content body -->\n</p:sp>\n```\n\n## File Updates\n\nWhen adding content, update these files:\n\n**`ppt/_rels/presentation.xml.rels`:**\n```xml\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"slides/slide1.xml\"/>\n<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster\" Target=\"slideMasters/slideMaster1.xml\"/>\n```\n\n**`ppt/slides/_rels/slide1.xml.rels`:**\n```xml\n<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/slideLayout1.xml\"/>\n<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image1.png\"/>\n```\n\n**`[Content_Types].xml`:**\n```xml\n<Default Extension=\"png\" ContentType=\"image/png\"/>\n<Default Extension=\"jpg\" ContentType=\"image/jpeg\"/>\n<Override PartName=\"/ppt/slides/slide1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\"/>\n```\n\n**`ppt/presentation.xml`:**\n```xml\n<p:sldIdLst>\n  <p:sldId id=\"256\" r:id=\"rId1\"/>\n  <p:sldId id=\"257\" r:id=\"rId2\"/>\n</p:sldIdLst>\n```\n\n**`docProps/app.xml`:** Update slide count and statistics\n```xml\n<Slides>2</Slides>\n<Paragraphs>10</Paragraphs>\n<Words>50</Words>\n```\n\n## Slide Operations\n\n### Adding a New Slide\nWhen adding a slide to the end of the presentation:\n\n1. **Create the slide file** (`ppt/slides/slideN.xml`)\n2. **Update `[Content_Types].xml`**: Add Override for the new slide\n3. **Update `ppt/_rels/presentation.xml.rels`**: Add relationship for the new slide\n4. **Update `ppt/presentation.xml`**: Add slide ID to `<p:sldIdLst>`\n5. **Create slide relationships** (`ppt/slides/_rels/slideN.xml.rels`) if needed\n6. **Update `docProps/app.xml`**: Increment slide count and update statistics (if present)\n\n### Duplicating a Slide\n1. Copy the source slide XML file with a new name\n2. Update all IDs in the new slide to be unique\n3. Follow the \"Adding a New Slide\" steps above\n4. **CRITICAL**: Remove or update any notes slide references in `_rels` files\n5. Remove references to unused media files\n\n### Reordering Slides\n1. **Update `ppt/presentation.xml`**: Reorder `<p:sldId>` elements in `<p:sldIdLst>`\n2. The order of `<p:sldId>` elements determines slide order\n3. Keep slide IDs and relationship IDs unchanged\n\nExample:\n```xml\n<!-- Original order -->\n<p:sldIdLst>\n  <p:sldId id=\"256\" r:id=\"rId2\"/>\n  <p:sldId id=\"257\" r:id=\"rId3\"/>\n  <p:sldId id=\"258\" r:id=\"rId4\"/>\n</p:sldIdLst>\n\n<!-- After moving slide 3 to position 2 -->\n<p:sldIdLst>\n  <p:sldId id=\"256\" r:id=\"rId2\"/>\n  <p:sldId id=\"258\" r:id=\"rId4\"/>\n  <p:sldId id=\"257\" r:id=\"rId3\"/>\n</p:sldIdLst>\n```\n\n### Deleting a Slide\n1. **Remove from `ppt/presentation.xml`**: Delete the `<p:sldId>` entry\n2. **Remove from `ppt/_rels/presentation.xml.rels`**: Delete the relationship\n3. **Remove from `[Content_Types].xml`**: Delete the Override entry\n4. **Delete files**: Remove `ppt/slides/slideN.xml` and `ppt/slides/_rels/slideN.xml.rels`\n5. **Update `docProps/app.xml`**: Decrement slide count and update statistics\n6. **Clean up unused media**: Remove orphaned images from `ppt/media/`\n\nNote: Don't renumber remaining slides - keep their original IDs and filenames.\n\n\n## Common Errors to Avoid\n\n- **Encodings**: Escape unicode characters in ASCII content: `\"` becomes `&#8220;`\n- **Images**: Add to `ppt/media/` and update relationship files\n- **Lists**: Omit bullets from list headers\n- **IDs**: Use valid hexadecimal values for UUIDs\n- **Themes**: Check all themes in `theme` directory for colors\n\n## Validation Checklist for Template-Based Presentations\n\n### Before Packing, Always:\n- **Clean unused resources**: Remove unreferenced media, fonts, and notes directories\n- **Fix Content_Types.xml**: Declare ALL slides, layouts, and themes present in the package\n- **Fix relationship IDs**: \n   - Remove font embed references if not using embedded fonts\n- **Remove broken references**: Check all `_rels` files for references to deleted resources\n\n### Common Template Duplication Pitfalls:\n- Multiple slides referencing the same notes slide after duplication\n- Image/media references from template slides that no longer exist\n- Font embedding references when fonts aren't included\n- Missing slideLayout declarations for layouts 12-25\n- docProps directory may not unpack - this is optional"
  },
  {
    "path": "document-skills/pptx/scripts/html2pptx.js",
    "content": "/**\n * html2pptx - Convert HTML slide to pptxgenjs slide with positioned elements\n *\n * USAGE:\n *   const pptx = new pptxgen();\n *   pptx.layout = 'LAYOUT_16x9';  // Must match HTML body dimensions\n *\n *   const { slide, placeholders } = await html2pptx('slide.html', pptx);\n *   slide.addChart(pptx.charts.LINE, data, placeholders[0]);\n *\n *   await pptx.writeFile('output.pptx');\n *\n * FEATURES:\n *   - Converts HTML to PowerPoint with accurate positioning\n *   - Supports text, images, shapes, and bullet lists\n *   - Extracts placeholder elements (class=\"placeholder\") with positions\n *   - Handles CSS gradients, borders, and margins\n *\n * VALIDATION:\n *   - Uses body width/height from HTML for viewport sizing\n *   - Throws error if HTML dimensions don't match presentation layout\n *   - Throws error if content overflows body (with overflow details)\n *\n * RETURNS:\n *   { slide, placeholders } where placeholders is an array of { id, x, y, w, h }\n */\n\nconst { chromium } = require('playwright');\nconst path = require('path');\nconst sharp = require('sharp');\n\nconst PT_PER_PX = 0.75;\nconst PX_PER_IN = 96;\nconst EMU_PER_IN = 914400;\n\n// Helper: Get body dimensions and check for overflow\nasync function getBodyDimensions(page) {\n  const bodyDimensions = await page.evaluate(() => {\n    const body = document.body;\n    const style = window.getComputedStyle(body);\n\n    return {\n      width: parseFloat(style.width),\n      height: parseFloat(style.height),\n      scrollWidth: body.scrollWidth,\n      scrollHeight: body.scrollHeight\n    };\n  });\n\n  const errors = [];\n  const widthOverflowPx = Math.max(0, bodyDimensions.scrollWidth - bodyDimensions.width - 1);\n  const heightOverflowPx = Math.max(0, bodyDimensions.scrollHeight - bodyDimensions.height - 1);\n\n  const widthOverflowPt = widthOverflowPx * PT_PER_PX;\n  const heightOverflowPt = heightOverflowPx * PT_PER_PX;\n\n  if (widthOverflowPt > 0 || heightOverflowPt > 0) {\n    const directions = [];\n    if (widthOverflowPt > 0) directions.push(`${widthOverflowPt.toFixed(1)}pt horizontally`);\n    if (heightOverflowPt > 0) directions.push(`${heightOverflowPt.toFixed(1)}pt vertically`);\n    const reminder = heightOverflowPt > 0 ? ' (Remember: leave 0.5\" margin at bottom of slide)' : '';\n    errors.push(`HTML content overflows body by ${directions.join(' and ')}${reminder}`);\n  }\n\n  return { ...bodyDimensions, errors };\n}\n\n// Helper: Validate dimensions match presentation layout\nfunction validateDimensions(bodyDimensions, pres) {\n  const errors = [];\n  const widthInches = bodyDimensions.width / PX_PER_IN;\n  const heightInches = bodyDimensions.height / PX_PER_IN;\n\n  if (pres.presLayout) {\n    const layoutWidth = pres.presLayout.width / EMU_PER_IN;\n    const layoutHeight = pres.presLayout.height / EMU_PER_IN;\n\n    if (Math.abs(layoutWidth - widthInches) > 0.1 || Math.abs(layoutHeight - heightInches) > 0.1) {\n      errors.push(\n        `HTML dimensions (${widthInches.toFixed(1)}\" × ${heightInches.toFixed(1)}\") ` +\n        `don't match presentation layout (${layoutWidth.toFixed(1)}\" × ${layoutHeight.toFixed(1)}\")`\n      );\n    }\n  }\n  return errors;\n}\n\nfunction validateTextBoxPosition(slideData, bodyDimensions) {\n  const errors = [];\n  const slideHeightInches = bodyDimensions.height / PX_PER_IN;\n  const minBottomMargin = 0.5; // 0.5 inches from bottom\n\n  for (const el of slideData.elements) {\n    // Check text elements (p, h1-h6, list)\n    if (['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'list'].includes(el.type)) {\n      const fontSize = el.style?.fontSize || 0;\n      const bottomEdge = el.position.y + el.position.h;\n      const distanceFromBottom = slideHeightInches - bottomEdge;\n\n      if (fontSize > 12 && distanceFromBottom < minBottomMargin) {\n        const getText = () => {\n          if (typeof el.text === 'string') return el.text;\n          if (Array.isArray(el.text)) return el.text.find(t => t.text)?.text || '';\n          if (Array.isArray(el.items)) return el.items.find(item => item.text)?.text || '';\n          return '';\n        };\n        const textPrefix = getText().substring(0, 50) + (getText().length > 50 ? '...' : '');\n\n        errors.push(\n          `Text box \"${textPrefix}\" ends too close to bottom edge ` +\n          `(${distanceFromBottom.toFixed(2)}\" from bottom, minimum ${minBottomMargin}\" required)`\n        );\n      }\n    }\n  }\n\n  return errors;\n}\n\n// Helper: Add background to slide\nasync function addBackground(slideData, targetSlide, tmpDir) {\n  if (slideData.background.type === 'image' && slideData.background.path) {\n    let imagePath = slideData.background.path.startsWith('file://')\n      ? slideData.background.path.replace('file://', '')\n      : slideData.background.path;\n    targetSlide.background = { path: imagePath };\n  } else if (slideData.background.type === 'color' && slideData.background.value) {\n    targetSlide.background = { color: slideData.background.value };\n  }\n}\n\n// Helper: Add elements to slide\nfunction addElements(slideData, targetSlide, pres) {\n  for (const el of slideData.elements) {\n    if (el.type === 'image') {\n      let imagePath = el.src.startsWith('file://') ? el.src.replace('file://', '') : el.src;\n      targetSlide.addImage({\n        path: imagePath,\n        x: el.position.x,\n        y: el.position.y,\n        w: el.position.w,\n        h: el.position.h\n      });\n    } else if (el.type === 'line') {\n      targetSlide.addShape(pres.ShapeType.line, {\n        x: el.x1,\n        y: el.y1,\n        w: el.x2 - el.x1,\n        h: el.y2 - el.y1,\n        line: { color: el.color, width: el.width }\n      });\n    } else if (el.type === 'shape') {\n      const shapeOptions = {\n        x: el.position.x,\n        y: el.position.y,\n        w: el.position.w,\n        h: el.position.h,\n        shape: el.shape.rectRadius > 0 ? pres.ShapeType.roundRect : pres.ShapeType.rect\n      };\n\n      if (el.shape.fill) {\n        shapeOptions.fill = { color: el.shape.fill };\n        if (el.shape.transparency != null) shapeOptions.fill.transparency = el.shape.transparency;\n      }\n      if (el.shape.line) shapeOptions.line = el.shape.line;\n      if (el.shape.rectRadius > 0) shapeOptions.rectRadius = el.shape.rectRadius;\n      if (el.shape.shadow) shapeOptions.shadow = el.shape.shadow;\n\n      targetSlide.addText(el.text || '', shapeOptions);\n    } else if (el.type === 'list') {\n      const listOptions = {\n        x: el.position.x,\n        y: el.position.y,\n        w: el.position.w,\n        h: el.position.h,\n        fontSize: el.style.fontSize,\n        fontFace: el.style.fontFace,\n        color: el.style.color,\n        align: el.style.align,\n        valign: 'top',\n        lineSpacing: el.style.lineSpacing,\n        paraSpaceBefore: el.style.paraSpaceBefore,\n        paraSpaceAfter: el.style.paraSpaceAfter,\n        margin: el.style.margin\n      };\n      if (el.style.margin) listOptions.margin = el.style.margin;\n      targetSlide.addText(el.items, listOptions);\n    } else {\n      // Check if text is single-line (height suggests one line)\n      const lineHeight = el.style.lineSpacing || el.style.fontSize * 1.2;\n      const isSingleLine = el.position.h <= lineHeight * 1.5;\n\n      let adjustedX = el.position.x;\n      let adjustedW = el.position.w;\n\n      // Make single-line text 2% wider to account for underestimate\n      if (isSingleLine) {\n        const widthIncrease = el.position.w * 0.02;\n        const align = el.style.align;\n\n        if (align === 'center') {\n          // Center: expand both sides\n          adjustedX = el.position.x - (widthIncrease / 2);\n          adjustedW = el.position.w + widthIncrease;\n        } else if (align === 'right') {\n          // Right: expand to the left\n          adjustedX = el.position.x - widthIncrease;\n          adjustedW = el.position.w + widthIncrease;\n        } else {\n          // Left (default): expand to the right\n          adjustedW = el.position.w + widthIncrease;\n        }\n      }\n\n      const textOptions = {\n        x: adjustedX,\n        y: el.position.y,\n        w: adjustedW,\n        h: el.position.h,\n        fontSize: el.style.fontSize,\n        fontFace: el.style.fontFace,\n        color: el.style.color,\n        bold: el.style.bold,\n        italic: el.style.italic,\n        underline: el.style.underline,\n        valign: 'top',\n        lineSpacing: el.style.lineSpacing,\n        paraSpaceBefore: el.style.paraSpaceBefore,\n        paraSpaceAfter: el.style.paraSpaceAfter,\n        inset: 0  // Remove default PowerPoint internal padding\n      };\n\n      if (el.style.align) textOptions.align = el.style.align;\n      if (el.style.margin) textOptions.margin = el.style.margin;\n      if (el.style.rotate !== undefined) textOptions.rotate = el.style.rotate;\n      if (el.style.transparency !== null && el.style.transparency !== undefined) textOptions.transparency = el.style.transparency;\n\n      targetSlide.addText(el.text, textOptions);\n    }\n  }\n}\n\n// Helper: Extract slide data from HTML page\nasync function extractSlideData(page) {\n  return await page.evaluate(() => {\n    const PT_PER_PX = 0.75;\n    const PX_PER_IN = 96;\n\n    // Fonts that are single-weight and should not have bold applied\n    // (applying bold causes PowerPoint to use faux bold which makes text wider)\n    const SINGLE_WEIGHT_FONTS = ['impact'];\n\n    // Helper: Check if a font should skip bold formatting\n    const shouldSkipBold = (fontFamily) => {\n      if (!fontFamily) return false;\n      const normalizedFont = fontFamily.toLowerCase().replace(/['\"]/g, '').split(',')[0].trim();\n      return SINGLE_WEIGHT_FONTS.includes(normalizedFont);\n    };\n\n    // Unit conversion helpers\n    const pxToInch = (px) => px / PX_PER_IN;\n    const pxToPoints = (pxStr) => parseFloat(pxStr) * PT_PER_PX;\n    const rgbToHex = (rgbStr) => {\n      // Handle transparent backgrounds by defaulting to white\n      if (rgbStr === 'rgba(0, 0, 0, 0)' || rgbStr === 'transparent') return 'FFFFFF';\n\n      const match = rgbStr.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n      if (!match) return 'FFFFFF';\n      return match.slice(1).map(n => parseInt(n).toString(16).padStart(2, '0')).join('');\n    };\n\n    const extractAlpha = (rgbStr) => {\n      const match = rgbStr.match(/rgba\\((\\d+),\\s*(\\d+),\\s*(\\d+),\\s*([\\d.]+)\\)/);\n      if (!match || !match[4]) return null;\n      const alpha = parseFloat(match[4]);\n      return Math.round((1 - alpha) * 100);\n    };\n\n    const applyTextTransform = (text, textTransform) => {\n      if (textTransform === 'uppercase') return text.toUpperCase();\n      if (textTransform === 'lowercase') return text.toLowerCase();\n      if (textTransform === 'capitalize') {\n        return text.replace(/\\b\\w/g, c => c.toUpperCase());\n      }\n      return text;\n    };\n\n    // Extract rotation angle from CSS transform and writing-mode\n    const getRotation = (transform, writingMode) => {\n      let angle = 0;\n\n      // Handle writing-mode first\n      // PowerPoint: 90° = text rotated 90° clockwise (reads top to bottom, letters upright)\n      // PowerPoint: 270° = text rotated 270° clockwise (reads bottom to top, letters upright)\n      if (writingMode === 'vertical-rl') {\n        // vertical-rl alone = text reads top to bottom = 90° in PowerPoint\n        angle = 90;\n      } else if (writingMode === 'vertical-lr') {\n        // vertical-lr alone = text reads bottom to top = 270° in PowerPoint\n        angle = 270;\n      }\n\n      // Then add any transform rotation\n      if (transform && transform !== 'none') {\n        // Try to match rotate() function\n        const rotateMatch = transform.match(/rotate\\((-?\\d+(?:\\.\\d+)?)deg\\)/);\n        if (rotateMatch) {\n          angle += parseFloat(rotateMatch[1]);\n        } else {\n          // Browser may compute as matrix - extract rotation from matrix\n          const matrixMatch = transform.match(/matrix\\(([^)]+)\\)/);\n          if (matrixMatch) {\n            const values = matrixMatch[1].split(',').map(parseFloat);\n            // matrix(a, b, c, d, e, f) where rotation = atan2(b, a)\n            const matrixAngle = Math.atan2(values[1], values[0]) * (180 / Math.PI);\n            angle += Math.round(matrixAngle);\n          }\n        }\n      }\n\n      // Normalize to 0-359 range\n      angle = angle % 360;\n      if (angle < 0) angle += 360;\n\n      return angle === 0 ? null : angle;\n    };\n\n    // Get position/dimensions accounting for rotation\n    const getPositionAndSize = (el, rect, rotation) => {\n      if (rotation === null) {\n        return { x: rect.left, y: rect.top, w: rect.width, h: rect.height };\n      }\n\n      // For 90° or 270° rotations, swap width and height\n      // because PowerPoint applies rotation to the original (unrotated) box\n      const isVertical = rotation === 90 || rotation === 270;\n\n      if (isVertical) {\n        // The browser shows us the rotated dimensions (tall box for vertical text)\n        // But PowerPoint needs the pre-rotation dimensions (wide box that will be rotated)\n        // So we swap: browser's height becomes PPT's width, browser's width becomes PPT's height\n        const centerX = rect.left + rect.width / 2;\n        const centerY = rect.top + rect.height / 2;\n\n        return {\n          x: centerX - rect.height / 2,\n          y: centerY - rect.width / 2,\n          w: rect.height,\n          h: rect.width\n        };\n      }\n\n      // For other rotations, use element's offset dimensions\n      const centerX = rect.left + rect.width / 2;\n      const centerY = rect.top + rect.height / 2;\n      return {\n        x: centerX - el.offsetWidth / 2,\n        y: centerY - el.offsetHeight / 2,\n        w: el.offsetWidth,\n        h: el.offsetHeight\n      };\n    };\n\n    // Parse CSS box-shadow into PptxGenJS shadow properties\n    const parseBoxShadow = (boxShadow) => {\n      if (!boxShadow || boxShadow === 'none') return null;\n\n      // Browser computed style format: \"rgba(0, 0, 0, 0.3) 2px 2px 8px 0px [inset]\"\n      // CSS format: \"[inset] 2px 2px 8px 0px rgba(0, 0, 0, 0.3)\"\n\n      const insetMatch = boxShadow.match(/inset/);\n\n      // IMPORTANT: PptxGenJS/PowerPoint doesn't properly support inset shadows\n      // Only process outer shadows to avoid file corruption\n      if (insetMatch) return null;\n\n      // Extract color first (rgba or rgb at start)\n      const colorMatch = boxShadow.match(/rgba?\\([^)]+\\)/);\n\n      // Extract numeric values (handles both px and pt units)\n      const parts = boxShadow.match(/([-\\d.]+)(px|pt)/g);\n\n      if (!parts || parts.length < 2) return null;\n\n      const offsetX = parseFloat(parts[0]);\n      const offsetY = parseFloat(parts[1]);\n      const blur = parts.length > 2 ? parseFloat(parts[2]) : 0;\n\n      // Calculate angle from offsets (in degrees, 0 = right, 90 = down)\n      let angle = 0;\n      if (offsetX !== 0 || offsetY !== 0) {\n        angle = Math.atan2(offsetY, offsetX) * (180 / Math.PI);\n        if (angle < 0) angle += 360;\n      }\n\n      // Calculate offset distance (hypotenuse)\n      const offset = Math.sqrt(offsetX * offsetX + offsetY * offsetY) * PT_PER_PX;\n\n      // Extract opacity from rgba\n      let opacity = 0.5;\n      if (colorMatch) {\n        const opacityMatch = colorMatch[0].match(/[\\d.]+\\)$/);\n        if (opacityMatch) {\n          opacity = parseFloat(opacityMatch[0].replace(')', ''));\n        }\n      }\n\n      return {\n        type: 'outer',\n        angle: Math.round(angle),\n        blur: blur * 0.75, // Convert to points\n        color: colorMatch ? rgbToHex(colorMatch[0]) : '000000',\n        offset: offset,\n        opacity\n      };\n    };\n\n    // Parse inline formatting tags (<b>, <i>, <u>, <strong>, <em>, <span>) into text runs\n    const parseInlineFormatting = (element, baseOptions = {}, runs = [], baseTextTransform = (x) => x) => {\n      let prevNodeIsText = false;\n\n      element.childNodes.forEach((node) => {\n        let textTransform = baseTextTransform;\n\n        const isText = node.nodeType === Node.TEXT_NODE || node.tagName === 'BR';\n        if (isText) {\n          const text = node.tagName === 'BR' ? '\\n' : textTransform(node.textContent.replace(/\\s+/g, ' '));\n          const prevRun = runs[runs.length - 1];\n          if (prevNodeIsText && prevRun) {\n            prevRun.text += text;\n          } else {\n            runs.push({ text, options: { ...baseOptions } });\n          }\n\n        } else if (node.nodeType === Node.ELEMENT_NODE && node.textContent.trim()) {\n          const options = { ...baseOptions };\n          const computed = window.getComputedStyle(node);\n\n          // Handle inline elements with computed styles\n          if (node.tagName === 'SPAN' || node.tagName === 'B' || node.tagName === 'STRONG' || node.tagName === 'I' || node.tagName === 'EM' || node.tagName === 'U') {\n            const isBold = computed.fontWeight === 'bold' || parseInt(computed.fontWeight) >= 600;\n            if (isBold && !shouldSkipBold(computed.fontFamily)) options.bold = true;\n            if (computed.fontStyle === 'italic') options.italic = true;\n            if (computed.textDecoration && computed.textDecoration.includes('underline')) options.underline = true;\n            if (computed.color && computed.color !== 'rgb(0, 0, 0)') {\n              options.color = rgbToHex(computed.color);\n              const transparency = extractAlpha(computed.color);\n              if (transparency !== null) options.transparency = transparency;\n            }\n            if (computed.fontSize) options.fontSize = pxToPoints(computed.fontSize);\n\n            // Apply text-transform on the span element itself\n            if (computed.textTransform && computed.textTransform !== 'none') {\n              const transformStr = computed.textTransform;\n              textTransform = (text) => applyTextTransform(text, transformStr);\n            }\n\n            // Validate: Check for margins on inline elements\n            if (computed.marginLeft && parseFloat(computed.marginLeft) > 0) {\n              errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-left which is not supported in PowerPoint. Remove margin from inline elements.`);\n            }\n            if (computed.marginRight && parseFloat(computed.marginRight) > 0) {\n              errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-right which is not supported in PowerPoint. Remove margin from inline elements.`);\n            }\n            if (computed.marginTop && parseFloat(computed.marginTop) > 0) {\n              errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-top which is not supported in PowerPoint. Remove margin from inline elements.`);\n            }\n            if (computed.marginBottom && parseFloat(computed.marginBottom) > 0) {\n              errors.push(`Inline element <${node.tagName.toLowerCase()}> has margin-bottom which is not supported in PowerPoint. Remove margin from inline elements.`);\n            }\n\n            // Recursively process the child node. This will flatten nested spans into multiple runs.\n            parseInlineFormatting(node, options, runs, textTransform);\n          }\n        }\n\n        prevNodeIsText = isText;\n      });\n\n      // Trim leading space from first run and trailing space from last run\n      if (runs.length > 0) {\n        runs[0].text = runs[0].text.replace(/^\\s+/, '');\n        runs[runs.length - 1].text = runs[runs.length - 1].text.replace(/\\s+$/, '');\n      }\n\n      return runs.filter(r => r.text.length > 0);\n    };\n\n    // Extract background from body (image or color)\n    const body = document.body;\n    const bodyStyle = window.getComputedStyle(body);\n    const bgImage = bodyStyle.backgroundImage;\n    const bgColor = bodyStyle.backgroundColor;\n\n    // Collect validation errors\n    const errors = [];\n\n    // Validate: Check for CSS gradients\n    if (bgImage && (bgImage.includes('linear-gradient') || bgImage.includes('radial-gradient'))) {\n      errors.push(\n        'CSS gradients are not supported. Use Sharp to rasterize gradients as PNG images first, ' +\n        'then reference with background-image: url(\\'gradient.png\\')'\n      );\n    }\n\n    let background;\n    if (bgImage && bgImage !== 'none') {\n      // Extract URL from url(\"...\") or url(...)\n      const urlMatch = bgImage.match(/url\\([\"']?([^\"')]+)[\"']?\\)/);\n      if (urlMatch) {\n        background = {\n          type: 'image',\n          path: urlMatch[1]\n        };\n      } else {\n        background = {\n          type: 'color',\n          value: rgbToHex(bgColor)\n        };\n      }\n    } else {\n      background = {\n        type: 'color',\n        value: rgbToHex(bgColor)\n      };\n    }\n\n    // Process all elements\n    const elements = [];\n    const placeholders = [];\n    const textTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'UL', 'OL', 'LI'];\n    const processed = new Set();\n\n    document.querySelectorAll('*').forEach((el) => {\n      if (processed.has(el)) return;\n\n      // Validate text elements don't have backgrounds, borders, or shadows\n      if (textTags.includes(el.tagName)) {\n        const computed = window.getComputedStyle(el);\n        const hasBg = computed.backgroundColor && computed.backgroundColor !== 'rgba(0, 0, 0, 0)';\n        const hasBorder = (computed.borderWidth && parseFloat(computed.borderWidth) > 0) ||\n                          (computed.borderTopWidth && parseFloat(computed.borderTopWidth) > 0) ||\n                          (computed.borderRightWidth && parseFloat(computed.borderRightWidth) > 0) ||\n                          (computed.borderBottomWidth && parseFloat(computed.borderBottomWidth) > 0) ||\n                          (computed.borderLeftWidth && parseFloat(computed.borderLeftWidth) > 0);\n        const hasShadow = computed.boxShadow && computed.boxShadow !== 'none';\n\n        if (hasBg || hasBorder || hasShadow) {\n          errors.push(\n            `Text element <${el.tagName.toLowerCase()}> has ${hasBg ? 'background' : hasBorder ? 'border' : 'shadow'}. ` +\n            'Backgrounds, borders, and shadows are only supported on <div> elements, not text elements.'\n          );\n          return;\n        }\n      }\n\n      // Extract placeholder elements (for charts, etc.)\n      if (el.className && el.className.includes('placeholder')) {\n        const rect = el.getBoundingClientRect();\n        if (rect.width === 0 || rect.height === 0) {\n          errors.push(\n            `Placeholder \"${el.id || 'unnamed'}\" has ${rect.width === 0 ? 'width: 0' : 'height: 0'}. Check the layout CSS.`\n          );\n        } else {\n          placeholders.push({\n            id: el.id || `placeholder-${placeholders.length}`,\n            x: pxToInch(rect.left),\n            y: pxToInch(rect.top),\n            w: pxToInch(rect.width),\n            h: pxToInch(rect.height)\n          });\n        }\n        processed.add(el);\n        return;\n      }\n\n      // Extract images\n      if (el.tagName === 'IMG') {\n        const rect = el.getBoundingClientRect();\n        if (rect.width > 0 && rect.height > 0) {\n          elements.push({\n            type: 'image',\n            src: el.src,\n            position: {\n              x: pxToInch(rect.left),\n              y: pxToInch(rect.top),\n              w: pxToInch(rect.width),\n              h: pxToInch(rect.height)\n            }\n          });\n          processed.add(el);\n          return;\n        }\n      }\n\n      // Extract DIVs with backgrounds/borders as shapes\n      const isContainer = el.tagName === 'DIV' && !textTags.includes(el.tagName);\n      if (isContainer) {\n        const computed = window.getComputedStyle(el);\n        const hasBg = computed.backgroundColor && computed.backgroundColor !== 'rgba(0, 0, 0, 0)';\n\n        // Validate: Check for unwrapped text content in DIV\n        for (const node of el.childNodes) {\n          if (node.nodeType === Node.TEXT_NODE) {\n            const text = node.textContent.trim();\n            if (text) {\n              errors.push(\n                `DIV element contains unwrapped text \"${text.substring(0, 50)}${text.length > 50 ? '...' : ''}\". ` +\n                'All text must be wrapped in <p>, <h1>-<h6>, <ul>, or <ol> tags to appear in PowerPoint.'\n              );\n            }\n          }\n        }\n\n        // Check for background images on shapes\n        const bgImage = computed.backgroundImage;\n        if (bgImage && bgImage !== 'none') {\n          errors.push(\n            'Background images on DIV elements are not supported. ' +\n            'Use solid colors or borders for shapes, or use slide.addImage() in PptxGenJS to layer images.'\n          );\n          return;\n        }\n\n        // Check for borders - both uniform and partial\n        const borderTop = computed.borderTopWidth;\n        const borderRight = computed.borderRightWidth;\n        const borderBottom = computed.borderBottomWidth;\n        const borderLeft = computed.borderLeftWidth;\n        const borders = [borderTop, borderRight, borderBottom, borderLeft].map(b => parseFloat(b) || 0);\n        const hasBorder = borders.some(b => b > 0);\n        const hasUniformBorder = hasBorder && borders.every(b => b === borders[0]);\n        const borderLines = [];\n\n        if (hasBorder && !hasUniformBorder) {\n          const rect = el.getBoundingClientRect();\n          const x = pxToInch(rect.left);\n          const y = pxToInch(rect.top);\n          const w = pxToInch(rect.width);\n          const h = pxToInch(rect.height);\n\n          // Collect lines to add after shape (inset by half the line width to center on edge)\n          if (parseFloat(borderTop) > 0) {\n            const widthPt = pxToPoints(borderTop);\n            const inset = (widthPt / 72) / 2; // Convert points to inches, then half\n            borderLines.push({\n              type: 'line',\n              x1: x, y1: y + inset, x2: x + w, y2: y + inset,\n              width: widthPt,\n              color: rgbToHex(computed.borderTopColor)\n            });\n          }\n          if (parseFloat(borderRight) > 0) {\n            const widthPt = pxToPoints(borderRight);\n            const inset = (widthPt / 72) / 2;\n            borderLines.push({\n              type: 'line',\n              x1: x + w - inset, y1: y, x2: x + w - inset, y2: y + h,\n              width: widthPt,\n              color: rgbToHex(computed.borderRightColor)\n            });\n          }\n          if (parseFloat(borderBottom) > 0) {\n            const widthPt = pxToPoints(borderBottom);\n            const inset = (widthPt / 72) / 2;\n            borderLines.push({\n              type: 'line',\n              x1: x, y1: y + h - inset, x2: x + w, y2: y + h - inset,\n              width: widthPt,\n              color: rgbToHex(computed.borderBottomColor)\n            });\n          }\n          if (parseFloat(borderLeft) > 0) {\n            const widthPt = pxToPoints(borderLeft);\n            const inset = (widthPt / 72) / 2;\n            borderLines.push({\n              type: 'line',\n              x1: x + inset, y1: y, x2: x + inset, y2: y + h,\n              width: widthPt,\n              color: rgbToHex(computed.borderLeftColor)\n            });\n          }\n        }\n\n        if (hasBg || hasBorder) {\n          const rect = el.getBoundingClientRect();\n          if (rect.width > 0 && rect.height > 0) {\n            const shadow = parseBoxShadow(computed.boxShadow);\n\n            // Only add shape if there's background or uniform border\n            if (hasBg || hasUniformBorder) {\n              elements.push({\n                type: 'shape',\n                text: '',  // Shape only - child text elements render on top\n                position: {\n                  x: pxToInch(rect.left),\n                  y: pxToInch(rect.top),\n                  w: pxToInch(rect.width),\n                  h: pxToInch(rect.height)\n                },\n                shape: {\n                  fill: hasBg ? rgbToHex(computed.backgroundColor) : null,\n                  transparency: hasBg ? extractAlpha(computed.backgroundColor) : null,\n                  line: hasUniformBorder ? {\n                    color: rgbToHex(computed.borderColor),\n                    width: pxToPoints(computed.borderWidth)\n                  } : null,\n                  // Convert border-radius to rectRadius (in inches)\n                  // % values: 50%+ = circle (1), <50% = percentage of min dimension\n                  // pt values: divide by 72 (72pt = 1 inch)\n                  // px values: divide by 96 (96px = 1 inch)\n                  rectRadius: (() => {\n                    const radius = computed.borderRadius;\n                    const radiusValue = parseFloat(radius);\n                    if (radiusValue === 0) return 0;\n\n                    if (radius.includes('%')) {\n                      if (radiusValue >= 50) return 1;\n                      // Calculate percentage of smaller dimension\n                      const minDim = Math.min(rect.width, rect.height);\n                      return (radiusValue / 100) * pxToInch(minDim);\n                    }\n\n                    if (radius.includes('pt')) return radiusValue / 72;\n                    return radiusValue / PX_PER_IN;\n                  })(),\n                  shadow: shadow\n                }\n              });\n            }\n\n            // Add partial border lines\n            elements.push(...borderLines);\n\n            processed.add(el);\n            return;\n          }\n        }\n      }\n\n      // Extract bullet lists as single text block\n      if (el.tagName === 'UL' || el.tagName === 'OL') {\n        const rect = el.getBoundingClientRect();\n        if (rect.width === 0 || rect.height === 0) return;\n\n        const liElements = Array.from(el.querySelectorAll('li'));\n        const items = [];\n        const ulComputed = window.getComputedStyle(el);\n        const ulPaddingLeftPt = pxToPoints(ulComputed.paddingLeft);\n\n        // Split: margin-left for bullet position, indent for text position\n        // margin-left + indent = ul padding-left\n        const marginLeft = ulPaddingLeftPt * 0.5;\n        const textIndent = ulPaddingLeftPt * 0.5;\n\n        liElements.forEach((li, idx) => {\n          const isLast = idx === liElements.length - 1;\n          const runs = parseInlineFormatting(li, { breakLine: false });\n          // Clean manual bullets from first run\n          if (runs.length > 0) {\n            runs[0].text = runs[0].text.replace(/^[•\\-\\*▪▸]\\s*/, '');\n            runs[0].options.bullet = { indent: textIndent };\n          }\n          // Set breakLine on last run\n          if (runs.length > 0 && !isLast) {\n            runs[runs.length - 1].options.breakLine = true;\n          }\n          items.push(...runs);\n        });\n\n        const computed = window.getComputedStyle(liElements[0] || el);\n\n        elements.push({\n          type: 'list',\n          items: items,\n          position: {\n            x: pxToInch(rect.left),\n            y: pxToInch(rect.top),\n            w: pxToInch(rect.width),\n            h: pxToInch(rect.height)\n          },\n          style: {\n            fontSize: pxToPoints(computed.fontSize),\n            fontFace: computed.fontFamily.split(',')[0].replace(/['\"]/g, '').trim(),\n            color: rgbToHex(computed.color),\n            transparency: extractAlpha(computed.color),\n            align: computed.textAlign === 'start' ? 'left' : computed.textAlign,\n            lineSpacing: computed.lineHeight && computed.lineHeight !== 'normal' ? pxToPoints(computed.lineHeight) : null,\n            paraSpaceBefore: 0,\n            paraSpaceAfter: pxToPoints(computed.marginBottom),\n            // PptxGenJS margin array is [left, right, bottom, top]\n            margin: [marginLeft, 0, 0, 0]\n          }\n        });\n\n        liElements.forEach(li => processed.add(li));\n        processed.add(el);\n        return;\n      }\n\n      // Extract text elements (P, H1, H2, etc.)\n      if (!textTags.includes(el.tagName)) return;\n\n      const rect = el.getBoundingClientRect();\n      const text = el.textContent.trim();\n      if (rect.width === 0 || rect.height === 0 || !text) return;\n\n      // Validate: Check for manual bullet symbols in text elements (not in lists)\n      if (el.tagName !== 'LI' && /^[•\\-\\*▪▸○●◆◇■□]\\s/.test(text.trimStart())) {\n        errors.push(\n          `Text element <${el.tagName.toLowerCase()}> starts with bullet symbol \"${text.substring(0, 20)}...\". ` +\n          'Use <ul> or <ol> lists instead of manual bullet symbols.'\n        );\n        return;\n      }\n\n      const computed = window.getComputedStyle(el);\n      const rotation = getRotation(computed.transform, computed.writingMode);\n      const { x, y, w, h } = getPositionAndSize(el, rect, rotation);\n\n      const baseStyle = {\n        fontSize: pxToPoints(computed.fontSize),\n        fontFace: computed.fontFamily.split(',')[0].replace(/['\"]/g, '').trim(),\n        color: rgbToHex(computed.color),\n        align: computed.textAlign === 'start' ? 'left' : computed.textAlign,\n        lineSpacing: pxToPoints(computed.lineHeight),\n        paraSpaceBefore: pxToPoints(computed.marginTop),\n        paraSpaceAfter: pxToPoints(computed.marginBottom),\n        // PptxGenJS margin array is [left, right, bottom, top] (not [top, right, bottom, left] as documented)\n        margin: [\n          pxToPoints(computed.paddingLeft),\n          pxToPoints(computed.paddingRight),\n          pxToPoints(computed.paddingBottom),\n          pxToPoints(computed.paddingTop)\n        ]\n      };\n\n      const transparency = extractAlpha(computed.color);\n      if (transparency !== null) baseStyle.transparency = transparency;\n\n      if (rotation !== null) baseStyle.rotate = rotation;\n\n      const hasFormatting = el.querySelector('b, i, u, strong, em, span, br');\n\n      if (hasFormatting) {\n        // Text with inline formatting\n        const transformStr = computed.textTransform;\n        const runs = parseInlineFormatting(el, {}, [], (str) => applyTextTransform(str, transformStr));\n\n        // Adjust lineSpacing based on largest fontSize in runs\n        const adjustedStyle = { ...baseStyle };\n        if (adjustedStyle.lineSpacing) {\n          const maxFontSize = Math.max(\n            adjustedStyle.fontSize,\n            ...runs.map(r => r.options?.fontSize || 0)\n          );\n          if (maxFontSize > adjustedStyle.fontSize) {\n            const lineHeightMultiplier = adjustedStyle.lineSpacing / adjustedStyle.fontSize;\n            adjustedStyle.lineSpacing = maxFontSize * lineHeightMultiplier;\n          }\n        }\n\n        elements.push({\n          type: el.tagName.toLowerCase(),\n          text: runs,\n          position: { x: pxToInch(x), y: pxToInch(y), w: pxToInch(w), h: pxToInch(h) },\n          style: adjustedStyle\n        });\n      } else {\n        // Plain text - inherit CSS formatting\n        const textTransform = computed.textTransform;\n        const transformedText = applyTextTransform(text, textTransform);\n\n        const isBold = computed.fontWeight === 'bold' || parseInt(computed.fontWeight) >= 600;\n\n        elements.push({\n          type: el.tagName.toLowerCase(),\n          text: transformedText,\n          position: { x: pxToInch(x), y: pxToInch(y), w: pxToInch(w), h: pxToInch(h) },\n          style: {\n            ...baseStyle,\n            bold: isBold && !shouldSkipBold(computed.fontFamily),\n            italic: computed.fontStyle === 'italic',\n            underline: computed.textDecoration.includes('underline')\n          }\n        });\n      }\n\n      processed.add(el);\n    });\n\n    return { background, elements, placeholders, errors };\n  });\n}\n\nasync function html2pptx(htmlFile, pres, options = {}) {\n  const {\n    tmpDir = process.env.TMPDIR || '/tmp',\n    slide = null\n  } = options;\n\n  try {\n    // Use Chrome on macOS, default Chromium on Unix\n    const launchOptions = { env: { TMPDIR: tmpDir } };\n    if (process.platform === 'darwin') {\n      launchOptions.channel = 'chrome';\n    }\n\n    const browser = await chromium.launch(launchOptions);\n\n    let bodyDimensions;\n    let slideData;\n\n    const filePath = path.isAbsolute(htmlFile) ? htmlFile : path.join(process.cwd(), htmlFile);\n    const validationErrors = [];\n\n    try {\n      const page = await browser.newPage();\n      page.on('console', (msg) => {\n        // Log the message text to your test runner's console\n        console.log(`Browser console: ${msg.text()}`);\n      });\n\n      await page.goto(`file://${filePath}`);\n\n      bodyDimensions = await getBodyDimensions(page);\n\n      await page.setViewportSize({\n        width: Math.round(bodyDimensions.width),\n        height: Math.round(bodyDimensions.height)\n      });\n\n      slideData = await extractSlideData(page);\n    } finally {\n      await browser.close();\n    }\n\n    // Collect all validation errors\n    if (bodyDimensions.errors && bodyDimensions.errors.length > 0) {\n      validationErrors.push(...bodyDimensions.errors);\n    }\n\n    const dimensionErrors = validateDimensions(bodyDimensions, pres);\n    if (dimensionErrors.length > 0) {\n      validationErrors.push(...dimensionErrors);\n    }\n\n    const textBoxPositionErrors = validateTextBoxPosition(slideData, bodyDimensions);\n    if (textBoxPositionErrors.length > 0) {\n      validationErrors.push(...textBoxPositionErrors);\n    }\n\n    if (slideData.errors && slideData.errors.length > 0) {\n      validationErrors.push(...slideData.errors);\n    }\n\n    // Throw all errors at once if any exist\n    if (validationErrors.length > 0) {\n      const errorMessage = validationErrors.length === 1\n        ? validationErrors[0]\n        : `Multiple validation errors found:\\n${validationErrors.map((e, i) => `  ${i + 1}. ${e}`).join('\\n')}`;\n      throw new Error(errorMessage);\n    }\n\n    const targetSlide = slide || pres.addSlide();\n\n    await addBackground(slideData, targetSlide, tmpDir);\n    addElements(slideData, targetSlide, pres);\n\n    return { slide: targetSlide, placeholders: slideData.placeholders };\n  } catch (error) {\n    if (!error.message.startsWith(htmlFile)) {\n      throw new Error(`${htmlFile}: ${error.message}`);\n    }\n    throw error;\n  }\n}\n\nmodule.exports = html2pptx;"
  },
  {
    "path": "document-skills/pptx/scripts/inventory.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nExtract structured text content from PowerPoint presentations.\n\nThis module provides functionality to:\n- Extract all text content from PowerPoint shapes\n- Preserve paragraph formatting (alignment, bullets, fonts, spacing)\n- Handle nested GroupShapes recursively with correct absolute positions\n- Sort shapes by visual position on slides\n- Filter out slide numbers and non-content placeholders\n- Export to JSON with clean, structured data\n\nClasses:\n    ParagraphData: Represents a text paragraph with formatting\n    ShapeData: Represents a shape with position and text content\n\nMain Functions:\n    extract_text_inventory: Extract all text from a presentation\n    save_inventory: Save extracted data to JSON\n\nUsage:\n    python inventory.py input.pptx output.json\n\"\"\"\n\nimport argparse\nimport json\nimport platform\nimport sys\nfrom dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom PIL import Image, ImageDraw, ImageFont\nfrom pptx import Presentation\nfrom pptx.enum.text import PP_ALIGN\nfrom pptx.shapes.base import BaseShape\n\n# Type aliases for cleaner signatures\nJsonValue = Union[str, int, float, bool, None]\nParagraphDict = Dict[str, JsonValue]\nShapeDict = Dict[\n    str, Union[str, float, bool, List[ParagraphDict], List[str], Dict[str, Any], None]\n]\nInventoryData = Dict[\n    str, Dict[str, \"ShapeData\"]\n]  # Dict of slide_id -> {shape_id -> ShapeData}\nInventoryDict = Dict[str, Dict[str, ShapeDict]]  # JSON-serializable inventory\n\n\ndef main():\n    \"\"\"Main entry point for command-line usage.\"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Extract text inventory from PowerPoint with proper GroupShape support.\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  python inventory.py presentation.pptx inventory.json\n    Extracts text inventory with correct absolute positions for grouped shapes\n\n  python inventory.py presentation.pptx inventory.json --issues-only\n    Extracts only text shapes that have overflow or overlap issues\n\nThe output JSON includes:\n  - All text content organized by slide and shape\n  - Correct absolute positions for shapes in groups\n  - Visual position and size in inches\n  - Paragraph properties and formatting\n  - Issue detection: text overflow and shape overlaps\n        \"\"\",\n    )\n\n    parser.add_argument(\"input\", help=\"Input PowerPoint file (.pptx)\")\n    parser.add_argument(\"output\", help=\"Output JSON file for inventory\")\n    parser.add_argument(\n        \"--issues-only\",\n        action=\"store_true\",\n        help=\"Include only text shapes that have overflow or overlap issues\",\n    )\n\n    args = parser.parse_args()\n\n    input_path = Path(args.input)\n    if not input_path.exists():\n        print(f\"Error: Input file not found: {args.input}\")\n        sys.exit(1)\n\n    if not input_path.suffix.lower() == \".pptx\":\n        print(\"Error: Input must be a PowerPoint file (.pptx)\")\n        sys.exit(1)\n\n    try:\n        print(f\"Extracting text inventory from: {args.input}\")\n        if args.issues_only:\n            print(\n                \"Filtering to include only text shapes with issues (overflow/overlap)\"\n            )\n        inventory = extract_text_inventory(input_path, issues_only=args.issues_only)\n\n        output_path = Path(args.output)\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n        save_inventory(inventory, output_path)\n\n        print(f\"Output saved to: {args.output}\")\n\n        # Report statistics\n        total_slides = len(inventory)\n        total_shapes = sum(len(shapes) for shapes in inventory.values())\n        if args.issues_only:\n            if total_shapes > 0:\n                print(\n                    f\"Found {total_shapes} text elements with issues in {total_slides} slides\"\n                )\n            else:\n                print(\"No issues discovered\")\n        else:\n            print(\n                f\"Found text in {total_slides} slides with {total_shapes} text elements\"\n            )\n\n    except Exception as e:\n        print(f\"Error processing presentation: {e}\")\n        import traceback\n\n        traceback.print_exc()\n        sys.exit(1)\n\n\n@dataclass\nclass ShapeWithPosition:\n    \"\"\"A shape with its absolute position on the slide.\"\"\"\n\n    shape: BaseShape\n    absolute_left: int  # in EMUs\n    absolute_top: int  # in EMUs\n\n\nclass ParagraphData:\n    \"\"\"Data structure for paragraph properties extracted from a PowerPoint paragraph.\"\"\"\n\n    def __init__(self, paragraph: Any):\n        \"\"\"Initialize from a PowerPoint paragraph object.\n\n        Args:\n            paragraph: The PowerPoint paragraph object\n        \"\"\"\n        self.text: str = paragraph.text.strip()\n        self.bullet: bool = False\n        self.level: Optional[int] = None\n        self.alignment: Optional[str] = None\n        self.space_before: Optional[float] = None\n        self.space_after: Optional[float] = None\n        self.font_name: Optional[str] = None\n        self.font_size: Optional[float] = None\n        self.bold: Optional[bool] = None\n        self.italic: Optional[bool] = None\n        self.underline: Optional[bool] = None\n        self.color: Optional[str] = None\n        self.theme_color: Optional[str] = None\n        self.line_spacing: Optional[float] = None\n\n        # Check for bullet formatting\n        if (\n            hasattr(paragraph, \"_p\")\n            and paragraph._p is not None\n            and paragraph._p.pPr is not None\n        ):\n            pPr = paragraph._p.pPr\n            ns = \"{http://schemas.openxmlformats.org/drawingml/2006/main}\"\n            if (\n                pPr.find(f\"{ns}buChar\") is not None\n                or pPr.find(f\"{ns}buAutoNum\") is not None\n            ):\n                self.bullet = True\n                if hasattr(paragraph, \"level\"):\n                    self.level = paragraph.level\n\n        # Add alignment if not LEFT (default)\n        if hasattr(paragraph, \"alignment\") and paragraph.alignment is not None:\n            alignment_map = {\n                PP_ALIGN.CENTER: \"CENTER\",\n                PP_ALIGN.RIGHT: \"RIGHT\",\n                PP_ALIGN.JUSTIFY: \"JUSTIFY\",\n            }\n            if paragraph.alignment in alignment_map:\n                self.alignment = alignment_map[paragraph.alignment]\n\n        # Add spacing properties if set\n        if hasattr(paragraph, \"space_before\") and paragraph.space_before:\n            self.space_before = paragraph.space_before.pt\n        if hasattr(paragraph, \"space_after\") and paragraph.space_after:\n            self.space_after = paragraph.space_after.pt\n\n        # Extract font properties from first run\n        if paragraph.runs:\n            first_run = paragraph.runs[0]\n            if hasattr(first_run, \"font\"):\n                font = first_run.font\n                if font.name:\n                    self.font_name = font.name\n                if font.size:\n                    self.font_size = font.size.pt\n                if font.bold is not None:\n                    self.bold = font.bold\n                if font.italic is not None:\n                    self.italic = font.italic\n                if font.underline is not None:\n                    self.underline = font.underline\n\n                # Handle color - both RGB and theme colors\n                try:\n                    # Try RGB color first\n                    if font.color.rgb:\n                        self.color = str(font.color.rgb)\n                except (AttributeError, TypeError):\n                    # Fall back to theme color\n                    try:\n                        if font.color.theme_color:\n                            self.theme_color = font.color.theme_color.name\n                    except (AttributeError, TypeError):\n                        pass\n\n        # Add line spacing if set\n        if hasattr(paragraph, \"line_spacing\") and paragraph.line_spacing is not None:\n            if hasattr(paragraph.line_spacing, \"pt\"):\n                self.line_spacing = round(paragraph.line_spacing.pt, 2)\n            else:\n                # Multiplier - convert to points\n                font_size = self.font_size if self.font_size else 12.0\n                self.line_spacing = round(paragraph.line_spacing * font_size, 2)\n\n    def to_dict(self) -> ParagraphDict:\n        \"\"\"Convert to dictionary for JSON serialization, excluding None values.\"\"\"\n        result: ParagraphDict = {\"text\": self.text}\n\n        # Add optional fields only if they have values\n        if self.bullet:\n            result[\"bullet\"] = self.bullet\n        if self.level is not None:\n            result[\"level\"] = self.level\n        if self.alignment:\n            result[\"alignment\"] = self.alignment\n        if self.space_before is not None:\n            result[\"space_before\"] = self.space_before\n        if self.space_after is not None:\n            result[\"space_after\"] = self.space_after\n        if self.font_name:\n            result[\"font_name\"] = self.font_name\n        if self.font_size is not None:\n            result[\"font_size\"] = self.font_size\n        if self.bold is not None:\n            result[\"bold\"] = self.bold\n        if self.italic is not None:\n            result[\"italic\"] = self.italic\n        if self.underline is not None:\n            result[\"underline\"] = self.underline\n        if self.color:\n            result[\"color\"] = self.color\n        if self.theme_color:\n            result[\"theme_color\"] = self.theme_color\n        if self.line_spacing is not None:\n            result[\"line_spacing\"] = self.line_spacing\n\n        return result\n\n\nclass ShapeData:\n    \"\"\"Data structure for shape properties extracted from a PowerPoint shape.\"\"\"\n\n    @staticmethod\n    def emu_to_inches(emu: int) -> float:\n        \"\"\"Convert EMUs (English Metric Units) to inches.\"\"\"\n        return emu / 914400.0\n\n    @staticmethod\n    def inches_to_pixels(inches: float, dpi: int = 96) -> int:\n        \"\"\"Convert inches to pixels at given DPI.\"\"\"\n        return int(inches * dpi)\n\n    @staticmethod\n    def get_font_path(font_name: str) -> Optional[str]:\n        \"\"\"Get the font file path for a given font name.\n\n        Args:\n            font_name: Name of the font (e.g., 'Arial', 'Calibri')\n\n        Returns:\n            Path to the font file, or None if not found\n        \"\"\"\n        system = platform.system()\n\n        # Common font file variations to try\n        font_variations = [\n            font_name,\n            font_name.lower(),\n            font_name.replace(\" \", \"\"),\n            font_name.replace(\" \", \"-\"),\n        ]\n\n        # Define font directories and extensions by platform\n        if system == \"Darwin\":  # macOS\n            font_dirs = [\n                \"/System/Library/Fonts/\",\n                \"/Library/Fonts/\",\n                \"~/Library/Fonts/\",\n            ]\n            extensions = [\".ttf\", \".otf\", \".ttc\", \".dfont\"]\n        else:  # Linux\n            font_dirs = [\n                \"/usr/share/fonts/truetype/\",\n                \"/usr/local/share/fonts/\",\n                \"~/.fonts/\",\n            ]\n            extensions = [\".ttf\", \".otf\"]\n\n        # Try to find the font file\n        from pathlib import Path\n\n        for font_dir in font_dirs:\n            font_dir_path = Path(font_dir).expanduser()\n            if not font_dir_path.exists():\n                continue\n\n            # First try exact matches\n            for variant in font_variations:\n                for ext in extensions:\n                    font_path = font_dir_path / f\"{variant}{ext}\"\n                    if font_path.exists():\n                        return str(font_path)\n\n            # Then try fuzzy matching - find files containing the font name\n            try:\n                for file_path in font_dir_path.iterdir():\n                    if file_path.is_file():\n                        file_name_lower = file_path.name.lower()\n                        font_name_lower = font_name.lower().replace(\" \", \"\")\n                        if font_name_lower in file_name_lower and any(\n                            file_name_lower.endswith(ext) for ext in extensions\n                        ):\n                            return str(file_path)\n            except (OSError, PermissionError):\n                continue\n\n        return None\n\n    @staticmethod\n    def get_slide_dimensions(slide: Any) -> tuple[Optional[int], Optional[int]]:\n        \"\"\"Get slide dimensions from slide object.\n\n        Args:\n            slide: Slide object\n\n        Returns:\n            Tuple of (width_emu, height_emu) or (None, None) if not found\n        \"\"\"\n        try:\n            prs = slide.part.package.presentation_part.presentation\n            return prs.slide_width, prs.slide_height\n        except (AttributeError, TypeError):\n            return None, None\n\n    @staticmethod\n    def get_default_font_size(shape: BaseShape, slide_layout: Any) -> Optional[float]:\n        \"\"\"Extract default font size from slide layout for a placeholder shape.\n\n        Args:\n            shape: Placeholder shape\n            slide_layout: Slide layout containing the placeholder definition\n\n        Returns:\n            Default font size in points, or None if not found\n        \"\"\"\n        try:\n            if not hasattr(shape, \"placeholder_format\"):\n                return None\n\n            shape_type = shape.placeholder_format.type  # type: ignore\n            for layout_placeholder in slide_layout.placeholders:\n                if layout_placeholder.placeholder_format.type == shape_type:\n                    # Find first defRPr element with sz (size) attribute\n                    for elem in layout_placeholder.element.iter():\n                        if \"defRPr\" in elem.tag and (sz := elem.get(\"sz\")):\n                            return float(sz) / 100.0  # Convert EMUs to points\n                    break\n        except Exception:\n            pass\n        return None\n\n    def __init__(\n        self,\n        shape: BaseShape,\n        absolute_left: Optional[int] = None,\n        absolute_top: Optional[int] = None,\n        slide: Optional[Any] = None,\n    ):\n        \"\"\"Initialize from a PowerPoint shape object.\n\n        Args:\n            shape: The PowerPoint shape object (should be pre-validated)\n            absolute_left: Absolute left position in EMUs (for shapes in groups)\n            absolute_top: Absolute top position in EMUs (for shapes in groups)\n            slide: Optional slide object to get dimensions and layout information\n        \"\"\"\n        self.shape = shape  # Store reference to original shape\n        self.shape_id: str = \"\"  # Will be set after sorting\n\n        # Get slide dimensions from slide object\n        self.slide_width_emu, self.slide_height_emu = (\n            self.get_slide_dimensions(slide) if slide else (None, None)\n        )\n\n        # Get placeholder type if applicable\n        self.placeholder_type: Optional[str] = None\n        self.default_font_size: Optional[float] = None\n        if hasattr(shape, \"is_placeholder\") and shape.is_placeholder:  # type: ignore\n            if shape.placeholder_format and shape.placeholder_format.type:  # type: ignore\n                self.placeholder_type = (\n                    str(shape.placeholder_format.type).split(\".\")[-1].split(\" \")[0]  # type: ignore\n                )\n\n                # Get default font size from layout\n                if slide and hasattr(slide, \"slide_layout\"):\n                    self.default_font_size = self.get_default_font_size(\n                        shape, slide.slide_layout\n                    )\n\n        # Get position information\n        # Use absolute positions if provided (for shapes in groups), otherwise use shape's position\n        left_emu = (\n            absolute_left\n            if absolute_left is not None\n            else (shape.left if hasattr(shape, \"left\") else 0)\n        )\n        top_emu = (\n            absolute_top\n            if absolute_top is not None\n            else (shape.top if hasattr(shape, \"top\") else 0)\n        )\n\n        self.left: float = round(self.emu_to_inches(left_emu), 2)  # type: ignore\n        self.top: float = round(self.emu_to_inches(top_emu), 2)  # type: ignore\n        self.width: float = round(\n            self.emu_to_inches(shape.width if hasattr(shape, \"width\") else 0),\n            2,  # type: ignore\n        )\n        self.height: float = round(\n            self.emu_to_inches(shape.height if hasattr(shape, \"height\") else 0),\n            2,  # type: ignore\n        )\n\n        # Store EMU positions for overflow calculations\n        self.left_emu = left_emu\n        self.top_emu = top_emu\n        self.width_emu = shape.width if hasattr(shape, \"width\") else 0\n        self.height_emu = shape.height if hasattr(shape, \"height\") else 0\n\n        # Calculate overflow status\n        self.frame_overflow_bottom: Optional[float] = None\n        self.slide_overflow_right: Optional[float] = None\n        self.slide_overflow_bottom: Optional[float] = None\n        self.overlapping_shapes: Dict[\n            str, float\n        ] = {}  # Dict of shape_id -> overlap area in sq inches\n        self.warnings: List[str] = []\n        self._estimate_frame_overflow()\n        self._calculate_slide_overflow()\n        self._detect_bullet_issues()\n\n    @property\n    def paragraphs(self) -> List[ParagraphData]:\n        \"\"\"Calculate paragraphs from the shape's text frame.\"\"\"\n        if not self.shape or not hasattr(self.shape, \"text_frame\"):\n            return []\n\n        paragraphs = []\n        for paragraph in self.shape.text_frame.paragraphs:  # type: ignore\n            if paragraph.text.strip():\n                paragraphs.append(ParagraphData(paragraph))\n        return paragraphs\n\n    def _get_default_font_size(self) -> int:\n        \"\"\"Get default font size from theme text styles or use conservative default.\"\"\"\n        try:\n            if not (\n                hasattr(self.shape, \"part\") and hasattr(self.shape.part, \"slide_layout\")\n            ):\n                return 14\n\n            slide_master = self.shape.part.slide_layout.slide_master  # type: ignore\n            if not hasattr(slide_master, \"element\"):\n                return 14\n\n            # Determine theme style based on placeholder type\n            style_name = \"bodyStyle\"  # Default\n            if self.placeholder_type and \"TITLE\" in self.placeholder_type:\n                style_name = \"titleStyle\"\n\n            # Find font size in theme styles\n            for child in slide_master.element.iter():\n                tag = child.tag.split(\"}\")[-1] if \"}\" in child.tag else child.tag\n                if tag == style_name:\n                    for elem in child.iter():\n                        if \"sz\" in elem.attrib:\n                            return int(elem.attrib[\"sz\"]) // 100\n        except Exception:\n            pass\n\n        return 14  # Conservative default for body text\n\n    def _get_usable_dimensions(self, text_frame) -> Tuple[int, int]:\n        \"\"\"Get usable width and height in pixels after accounting for margins.\"\"\"\n        # Default PowerPoint margins in inches\n        margins = {\"top\": 0.05, \"bottom\": 0.05, \"left\": 0.1, \"right\": 0.1}\n\n        # Override with actual margins if set\n        if hasattr(text_frame, \"margin_top\") and text_frame.margin_top:\n            margins[\"top\"] = self.emu_to_inches(text_frame.margin_top)\n        if hasattr(text_frame, \"margin_bottom\") and text_frame.margin_bottom:\n            margins[\"bottom\"] = self.emu_to_inches(text_frame.margin_bottom)\n        if hasattr(text_frame, \"margin_left\") and text_frame.margin_left:\n            margins[\"left\"] = self.emu_to_inches(text_frame.margin_left)\n        if hasattr(text_frame, \"margin_right\") and text_frame.margin_right:\n            margins[\"right\"] = self.emu_to_inches(text_frame.margin_right)\n\n        # Calculate usable area\n        usable_width = self.width - margins[\"left\"] - margins[\"right\"]\n        usable_height = self.height - margins[\"top\"] - margins[\"bottom\"]\n\n        # Convert to pixels\n        return (\n            self.inches_to_pixels(usable_width),\n            self.inches_to_pixels(usable_height),\n        )\n\n    def _wrap_text_line(self, line: str, max_width_px: int, draw, font) -> List[str]:\n        \"\"\"Wrap a single line of text to fit within max_width_px.\"\"\"\n        if not line:\n            return [\"\"]\n\n        # Use textlength for efficient width calculation\n        if draw.textlength(line, font=font) <= max_width_px:\n            return [line]\n\n        # Need to wrap - split into words\n        wrapped = []\n        words = line.split(\" \")\n        current_line = \"\"\n\n        for word in words:\n            test_line = current_line + (\" \" if current_line else \"\") + word\n            if draw.textlength(test_line, font=font) <= max_width_px:\n                current_line = test_line\n            else:\n                if current_line:\n                    wrapped.append(current_line)\n                current_line = word\n\n        if current_line:\n            wrapped.append(current_line)\n\n        return wrapped\n\n    def _estimate_frame_overflow(self) -> None:\n        \"\"\"Estimate if text overflows the shape bounds using PIL text measurement.\"\"\"\n        if not self.shape or not hasattr(self.shape, \"text_frame\"):\n            return\n\n        text_frame = self.shape.text_frame  # type: ignore\n        if not text_frame or not text_frame.paragraphs:\n            return\n\n        # Get usable dimensions after accounting for margins\n        usable_width_px, usable_height_px = self._get_usable_dimensions(text_frame)\n        if usable_width_px <= 0 or usable_height_px <= 0:\n            return\n\n        # Set up PIL for text measurement\n        dummy_img = Image.new(\"RGB\", (1, 1))\n        draw = ImageDraw.Draw(dummy_img)\n\n        # Get default font size from placeholder or use conservative estimate\n        default_font_size = self._get_default_font_size()\n\n        # Calculate total height of all paragraphs\n        total_height_px = 0\n\n        for para_idx, paragraph in enumerate(text_frame.paragraphs):\n            if not paragraph.text.strip():\n                continue\n\n            para_data = ParagraphData(paragraph)\n\n            # Load font for this paragraph\n            font_name = para_data.font_name or \"Arial\"\n            font_size = int(para_data.font_size or default_font_size)\n\n            font = None\n            font_path = self.get_font_path(font_name)\n            if font_path:\n                try:\n                    font = ImageFont.truetype(font_path, size=font_size)\n                except Exception:\n                    font = ImageFont.load_default()\n            else:\n                font = ImageFont.load_default()\n\n            # Wrap all lines in this paragraph\n            all_wrapped_lines = []\n            for line in paragraph.text.split(\"\\n\"):\n                wrapped = self._wrap_text_line(line, usable_width_px, draw, font)\n                all_wrapped_lines.extend(wrapped)\n\n            if all_wrapped_lines:\n                # Calculate line height\n                if para_data.line_spacing:\n                    # Custom line spacing explicitly set\n                    line_height_px = para_data.line_spacing * 96 / 72\n                else:\n                    # PowerPoint default single spacing (1.0x font size)\n                    line_height_px = font_size * 96 / 72\n\n                # Add space_before (except first paragraph)\n                if para_idx > 0 and para_data.space_before:\n                    total_height_px += para_data.space_before * 96 / 72\n\n                # Add paragraph text height\n                total_height_px += len(all_wrapped_lines) * line_height_px\n\n                # Add space_after\n                if para_data.space_after:\n                    total_height_px += para_data.space_after * 96 / 72\n\n        # Check for overflow (ignore negligible overflows <= 0.05\")\n        if total_height_px > usable_height_px:\n            overflow_px = total_height_px - usable_height_px\n            overflow_inches = round(overflow_px / 96.0, 2)\n            if overflow_inches > 0.05:  # Only report significant overflows\n                self.frame_overflow_bottom = overflow_inches\n\n    def _calculate_slide_overflow(self) -> None:\n        \"\"\"Calculate if shape overflows the slide boundaries.\"\"\"\n        if self.slide_width_emu is None or self.slide_height_emu is None:\n            return\n\n        # Check right overflow (ignore negligible overflows <= 0.01\")\n        right_edge_emu = self.left_emu + self.width_emu\n        if right_edge_emu > self.slide_width_emu:\n            overflow_emu = right_edge_emu - self.slide_width_emu\n            overflow_inches = round(self.emu_to_inches(overflow_emu), 2)\n            if overflow_inches > 0.01:  # Only report significant overflows\n                self.slide_overflow_right = overflow_inches\n\n        # Check bottom overflow (ignore negligible overflows <= 0.01\")\n        bottom_edge_emu = self.top_emu + self.height_emu\n        if bottom_edge_emu > self.slide_height_emu:\n            overflow_emu = bottom_edge_emu - self.slide_height_emu\n            overflow_inches = round(self.emu_to_inches(overflow_emu), 2)\n            if overflow_inches > 0.01:  # Only report significant overflows\n                self.slide_overflow_bottom = overflow_inches\n\n    def _detect_bullet_issues(self) -> None:\n        \"\"\"Detect bullet point formatting issues in paragraphs.\"\"\"\n        if not self.shape or not hasattr(self.shape, \"text_frame\"):\n            return\n\n        text_frame = self.shape.text_frame  # type: ignore\n        if not text_frame or not text_frame.paragraphs:\n            return\n\n        # Common bullet symbols that indicate manual bullets\n        bullet_symbols = [\"•\", \"●\", \"○\"]\n\n        for paragraph in text_frame.paragraphs:\n            text = paragraph.text.strip()\n            # Check for manual bullet symbols\n            if text and any(text.startswith(symbol + \" \") for symbol in bullet_symbols):\n                self.warnings.append(\n                    \"manual_bullet_symbol: use proper bullet formatting\"\n                )\n                break\n\n    @property\n    def has_any_issues(self) -> bool:\n        \"\"\"Check if shape has any issues (overflow, overlap, or warnings).\"\"\"\n        return (\n            self.frame_overflow_bottom is not None\n            or self.slide_overflow_right is not None\n            or self.slide_overflow_bottom is not None\n            or len(self.overlapping_shapes) > 0\n            or len(self.warnings) > 0\n        )\n\n    def to_dict(self) -> ShapeDict:\n        \"\"\"Convert to dictionary for JSON serialization.\"\"\"\n        result: ShapeDict = {\n            \"left\": self.left,\n            \"top\": self.top,\n            \"width\": self.width,\n            \"height\": self.height,\n        }\n\n        # Add optional fields if present\n        if self.placeholder_type:\n            result[\"placeholder_type\"] = self.placeholder_type\n\n        if self.default_font_size:\n            result[\"default_font_size\"] = self.default_font_size\n\n        # Add overflow information only if there is overflow\n        overflow_data = {}\n\n        # Add frame overflow if present\n        if self.frame_overflow_bottom is not None:\n            overflow_data[\"frame\"] = {\"overflow_bottom\": self.frame_overflow_bottom}\n\n        # Add slide overflow if present\n        slide_overflow = {}\n        if self.slide_overflow_right is not None:\n            slide_overflow[\"overflow_right\"] = self.slide_overflow_right\n        if self.slide_overflow_bottom is not None:\n            slide_overflow[\"overflow_bottom\"] = self.slide_overflow_bottom\n        if slide_overflow:\n            overflow_data[\"slide\"] = slide_overflow\n\n        # Only add overflow field if there is overflow\n        if overflow_data:\n            result[\"overflow\"] = overflow_data\n\n        # Add overlap field if there are overlapping shapes\n        if self.overlapping_shapes:\n            result[\"overlap\"] = {\"overlapping_shapes\": self.overlapping_shapes}\n\n        # Add warnings field if there are warnings\n        if self.warnings:\n            result[\"warnings\"] = self.warnings\n\n        # Add paragraphs after placeholder_type\n        result[\"paragraphs\"] = [para.to_dict() for para in self.paragraphs]\n\n        return result\n\n\ndef is_valid_shape(shape: BaseShape) -> bool:\n    \"\"\"Check if a shape contains meaningful text content.\"\"\"\n    # Must have a text frame with content\n    if not hasattr(shape, \"text_frame\") or not shape.text_frame:  # type: ignore\n        return False\n\n    text = shape.text_frame.text.strip()  # type: ignore\n    if not text:\n        return False\n\n    # Skip slide numbers and numeric footers\n    if hasattr(shape, \"is_placeholder\") and shape.is_placeholder:  # type: ignore\n        if shape.placeholder_format and shape.placeholder_format.type:  # type: ignore\n            placeholder_type = (\n                str(shape.placeholder_format.type).split(\".\")[-1].split(\" \")[0]  # type: ignore\n            )\n            if placeholder_type == \"SLIDE_NUMBER\":\n                return False\n            if placeholder_type == \"FOOTER\" and text.isdigit():\n                return False\n\n    return True\n\n\ndef collect_shapes_with_absolute_positions(\n    shape: BaseShape, parent_left: int = 0, parent_top: int = 0\n) -> List[ShapeWithPosition]:\n    \"\"\"Recursively collect all shapes with valid text, calculating absolute positions.\n\n    For shapes within groups, their positions are relative to the group.\n    This function calculates the absolute position on the slide by accumulating\n    parent group offsets.\n\n    Args:\n        shape: The shape to process\n        parent_left: Accumulated left offset from parent groups (in EMUs)\n        parent_top: Accumulated top offset from parent groups (in EMUs)\n\n    Returns:\n        List of ShapeWithPosition objects with absolute positions\n    \"\"\"\n    if hasattr(shape, \"shapes\"):  # GroupShape\n        result = []\n        # Get this group's position\n        group_left = shape.left if hasattr(shape, \"left\") else 0\n        group_top = shape.top if hasattr(shape, \"top\") else 0\n\n        # Calculate absolute position for this group\n        abs_group_left = parent_left + group_left\n        abs_group_top = parent_top + group_top\n\n        # Process children with accumulated offsets\n        for child in shape.shapes:  # type: ignore\n            result.extend(\n                collect_shapes_with_absolute_positions(\n                    child, abs_group_left, abs_group_top\n                )\n            )\n        return result\n\n    # Regular shape - check if it has valid text\n    if is_valid_shape(shape):\n        # Calculate absolute position\n        shape_left = shape.left if hasattr(shape, \"left\") else 0\n        shape_top = shape.top if hasattr(shape, \"top\") else 0\n\n        return [\n            ShapeWithPosition(\n                shape=shape,\n                absolute_left=parent_left + shape_left,\n                absolute_top=parent_top + shape_top,\n            )\n        ]\n\n    return []\n\n\ndef sort_shapes_by_position(shapes: List[ShapeData]) -> List[ShapeData]:\n    \"\"\"Sort shapes by visual position (top-to-bottom, left-to-right).\n\n    Shapes within 0.5 inches vertically are considered on the same row.\n    \"\"\"\n    if not shapes:\n        return shapes\n\n    # Sort by top position first\n    shapes = sorted(shapes, key=lambda s: (s.top, s.left))\n\n    # Group shapes by row (within 0.5 inches vertically)\n    result = []\n    row = [shapes[0]]\n    row_top = shapes[0].top\n\n    for shape in shapes[1:]:\n        if abs(shape.top - row_top) <= 0.5:\n            row.append(shape)\n        else:\n            # Sort current row by left position and add to result\n            result.extend(sorted(row, key=lambda s: s.left))\n            row = [shape]\n            row_top = shape.top\n\n    # Don't forget the last row\n    result.extend(sorted(row, key=lambda s: s.left))\n    return result\n\n\ndef calculate_overlap(\n    rect1: Tuple[float, float, float, float],\n    rect2: Tuple[float, float, float, float],\n    tolerance: float = 0.05,\n) -> Tuple[bool, float]:\n    \"\"\"Calculate if and how much two rectangles overlap.\n\n    Args:\n        rect1: (left, top, width, height) of first rectangle in inches\n        rect2: (left, top, width, height) of second rectangle in inches\n        tolerance: Minimum overlap in inches to consider as overlapping (default: 0.05\")\n\n    Returns:\n        Tuple of (overlaps, overlap_area) where:\n        - overlaps: True if rectangles overlap by more than tolerance\n        - overlap_area: Area of overlap in square inches\n    \"\"\"\n    left1, top1, w1, h1 = rect1\n    left2, top2, w2, h2 = rect2\n\n    # Calculate overlap dimensions\n    overlap_width = min(left1 + w1, left2 + w2) - max(left1, left2)\n    overlap_height = min(top1 + h1, top2 + h2) - max(top1, top2)\n\n    # Check if there's meaningful overlap (more than tolerance)\n    if overlap_width > tolerance and overlap_height > tolerance:\n        # Calculate overlap area in square inches\n        overlap_area = overlap_width * overlap_height\n        return True, round(overlap_area, 2)\n\n    return False, 0\n\n\ndef detect_overlaps(shapes: List[ShapeData]) -> None:\n    \"\"\"Detect overlapping shapes and update their overlapping_shapes dictionaries.\n\n    This function requires each ShapeData to have its shape_id already set.\n    It modifies the shapes in-place, adding shape IDs with overlap areas in square inches.\n\n    Args:\n        shapes: List of ShapeData objects with shape_id attributes set\n    \"\"\"\n    n = len(shapes)\n\n    # Compare each pair of shapes\n    for i in range(n):\n        for j in range(i + 1, n):\n            shape1 = shapes[i]\n            shape2 = shapes[j]\n\n            # Ensure shape IDs are set\n            assert shape1.shape_id, f\"Shape at index {i} has no shape_id\"\n            assert shape2.shape_id, f\"Shape at index {j} has no shape_id\"\n\n            rect1 = (shape1.left, shape1.top, shape1.width, shape1.height)\n            rect2 = (shape2.left, shape2.top, shape2.width, shape2.height)\n\n            overlaps, overlap_area = calculate_overlap(rect1, rect2)\n\n            if overlaps:\n                # Add shape IDs with overlap area in square inches\n                shape1.overlapping_shapes[shape2.shape_id] = overlap_area\n                shape2.overlapping_shapes[shape1.shape_id] = overlap_area\n\n\ndef extract_text_inventory(\n    pptx_path: Path, prs: Optional[Any] = None, issues_only: bool = False\n) -> InventoryData:\n    \"\"\"Extract text content from all slides in a PowerPoint presentation.\n\n    Args:\n        pptx_path: Path to the PowerPoint file\n        prs: Optional Presentation object to use. If not provided, will load from pptx_path.\n        issues_only: If True, only include shapes that have overflow or overlap issues\n\n    Returns a nested dictionary: {slide-N: {shape-N: ShapeData}}\n    Shapes are sorted by visual position (top-to-bottom, left-to-right).\n    The ShapeData objects contain the full shape information and can be\n    converted to dictionaries for JSON serialization using to_dict().\n    \"\"\"\n    if prs is None:\n        prs = Presentation(str(pptx_path))\n    inventory: InventoryData = {}\n\n    for slide_idx, slide in enumerate(prs.slides):\n        # Collect all valid shapes from this slide with absolute positions\n        shapes_with_positions = []\n        for shape in slide.shapes:  # type: ignore\n            shapes_with_positions.extend(collect_shapes_with_absolute_positions(shape))\n\n        if not shapes_with_positions:\n            continue\n\n        # Convert to ShapeData with absolute positions and slide reference\n        shape_data_list = [\n            ShapeData(\n                swp.shape,\n                swp.absolute_left,\n                swp.absolute_top,\n                slide,\n            )\n            for swp in shapes_with_positions\n        ]\n\n        # Sort by visual position and assign stable IDs in one step\n        sorted_shapes = sort_shapes_by_position(shape_data_list)\n        for idx, shape_data in enumerate(sorted_shapes):\n            shape_data.shape_id = f\"shape-{idx}\"\n\n        # Detect overlaps using the stable shape IDs\n        if len(sorted_shapes) > 1:\n            detect_overlaps(sorted_shapes)\n\n        # Filter for issues only if requested (after overlap detection)\n        if issues_only:\n            sorted_shapes = [sd for sd in sorted_shapes if sd.has_any_issues]\n\n        if not sorted_shapes:\n            continue\n\n        # Create slide inventory using the stable shape IDs\n        inventory[f\"slide-{slide_idx}\"] = {\n            shape_data.shape_id: shape_data for shape_data in sorted_shapes\n        }\n\n    return inventory\n\n\ndef get_inventory_as_dict(pptx_path: Path, issues_only: bool = False) -> InventoryDict:\n    \"\"\"Extract text inventory and return as JSON-serializable dictionaries.\n\n    This is a convenience wrapper around extract_text_inventory that returns\n    dictionaries instead of ShapeData objects, useful for testing and direct\n    JSON serialization.\n\n    Args:\n        pptx_path: Path to the PowerPoint file\n        issues_only: If True, only include shapes that have overflow or overlap issues\n\n    Returns:\n        Nested dictionary with all data serialized for JSON\n    \"\"\"\n    inventory = extract_text_inventory(pptx_path, issues_only=issues_only)\n\n    # Convert ShapeData objects to dictionaries\n    dict_inventory: InventoryDict = {}\n    for slide_key, shapes in inventory.items():\n        dict_inventory[slide_key] = {\n            shape_key: shape_data.to_dict() for shape_key, shape_data in shapes.items()\n        }\n\n    return dict_inventory\n\n\ndef save_inventory(inventory: InventoryData, output_path: Path) -> None:\n    \"\"\"Save inventory to JSON file with proper formatting.\n\n    Converts ShapeData objects to dictionaries for JSON serialization.\n    \"\"\"\n    # Convert ShapeData objects to dictionaries\n    json_inventory: InventoryDict = {}\n    for slide_key, shapes in inventory.items():\n        json_inventory[slide_key] = {\n            shape_key: shape_data.to_dict() for shape_key, shape_data in shapes.items()\n        }\n\n    with open(output_path, \"w\", encoding=\"utf-8\") as f:\n        json.dump(json_inventory, f, indent=2, ensure_ascii=False)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/pptx/scripts/rearrange.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nRearrange PowerPoint slides based on a sequence of indices.\n\nUsage:\n    python rearrange.py template.pptx output.pptx 0,34,34,50,52\n\nThis will create output.pptx using slides from template.pptx in the specified order.\nSlides can be repeated (e.g., 34 appears twice).\n\"\"\"\n\nimport argparse\nimport shutil\nimport sys\nfrom copy import deepcopy\nfrom pathlib import Path\n\nimport six\nfrom pptx import Presentation\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description=\"Rearrange PowerPoint slides based on a sequence of indices.\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  python rearrange.py template.pptx output.pptx 0,34,34,50,52\n    Creates output.pptx using slides 0, 34 (twice), 50, and 52 from template.pptx\n\n  python rearrange.py template.pptx output.pptx 5,3,1,2,4\n    Creates output.pptx with slides reordered as specified\n\nNote: Slide indices are 0-based (first slide is 0, second is 1, etc.)\n        \"\"\",\n    )\n\n    parser.add_argument(\"template\", help=\"Path to template PPTX file\")\n    parser.add_argument(\"output\", help=\"Path for output PPTX file\")\n    parser.add_argument(\n        \"sequence\", help=\"Comma-separated sequence of slide indices (0-based)\"\n    )\n\n    args = parser.parse_args()\n\n    # Parse the slide sequence\n    try:\n        slide_sequence = [int(x.strip()) for x in args.sequence.split(\",\")]\n    except ValueError:\n        print(\n            \"Error: Invalid sequence format. Use comma-separated integers (e.g., 0,34,34,50,52)\"\n        )\n        sys.exit(1)\n\n    # Check template exists\n    template_path = Path(args.template)\n    if not template_path.exists():\n        print(f\"Error: Template file not found: {args.template}\")\n        sys.exit(1)\n\n    # Create output directory if needed\n    output_path = Path(args.output)\n    output_path.parent.mkdir(parents=True, exist_ok=True)\n\n    try:\n        rearrange_presentation(template_path, output_path, slide_sequence)\n    except ValueError as e:\n        print(f\"Error: {e}\")\n        sys.exit(1)\n    except Exception as e:\n        print(f\"Error processing presentation: {e}\")\n        sys.exit(1)\n\n\ndef duplicate_slide(pres, index):\n    \"\"\"Duplicate a slide in the presentation.\"\"\"\n    source = pres.slides[index]\n\n    # Use source's layout to preserve formatting\n    new_slide = pres.slides.add_slide(source.slide_layout)\n\n    # Collect all image and media relationships from the source slide\n    image_rels = {}\n    for rel_id, rel in six.iteritems(source.part.rels):\n        if \"image\" in rel.reltype or \"media\" in rel.reltype:\n            image_rels[rel_id] = rel\n\n    # CRITICAL: Clear placeholder shapes to avoid duplicates\n    for shape in new_slide.shapes:\n        sp = shape.element\n        sp.getparent().remove(sp)\n\n    # Copy all shapes from source\n    for shape in source.shapes:\n        el = shape.element\n        new_el = deepcopy(el)\n        new_slide.shapes._spTree.insert_element_before(new_el, \"p:extLst\")\n\n        # Handle picture shapes - need to update the blip reference\n        # Look for all blip elements (they can be in pic or other contexts)\n        # Using the element's own xpath method without namespaces argument\n        blips = new_el.xpath(\".//a:blip[@r:embed]\")\n        for blip in blips:\n            old_rId = blip.get(\n                \"{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed\"\n            )\n            if old_rId in image_rels:\n                # Create a new relationship in the destination slide for this image\n                old_rel = image_rels[old_rId]\n                # get_or_add returns the rId directly, or adds and returns new rId\n                new_rId = new_slide.part.rels.get_or_add(\n                    old_rel.reltype, old_rel._target\n                )\n                # Update the blip's embed reference to use the new relationship ID\n                blip.set(\n                    \"{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed\",\n                    new_rId,\n                )\n\n    # Copy any additional image/media relationships that might be referenced elsewhere\n    for rel_id, rel in image_rels.items():\n        try:\n            new_slide.part.rels.get_or_add(rel.reltype, rel._target)\n        except Exception:\n            pass  # Relationship might already exist\n\n    return new_slide\n\n\ndef delete_slide(pres, index):\n    \"\"\"Delete a slide from the presentation.\"\"\"\n    rId = pres.slides._sldIdLst[index].rId\n    pres.part.drop_rel(rId)\n    del pres.slides._sldIdLst[index]\n\n\ndef reorder_slides(pres, slide_index, target_index):\n    \"\"\"Move a slide from one position to another.\"\"\"\n    slides = pres.slides._sldIdLst\n\n    # Remove slide element from current position\n    slide_element = slides[slide_index]\n    slides.remove(slide_element)\n\n    # Insert at target position\n    slides.insert(target_index, slide_element)\n\n\ndef rearrange_presentation(template_path, output_path, slide_sequence):\n    \"\"\"\n    Create a new presentation with slides from template in specified order.\n\n    Args:\n        template_path: Path to template PPTX file\n        output_path: Path for output PPTX file\n        slide_sequence: List of slide indices (0-based) to include\n    \"\"\"\n    # Copy template to preserve dimensions and theme\n    if template_path != output_path:\n        shutil.copy2(template_path, output_path)\n        prs = Presentation(output_path)\n    else:\n        prs = Presentation(template_path)\n\n    total_slides = len(prs.slides)\n\n    # Validate indices\n    for idx in slide_sequence:\n        if idx < 0 or idx >= total_slides:\n            raise ValueError(f\"Slide index {idx} out of range (0-{total_slides - 1})\")\n\n    # Track original slides and their duplicates\n    slide_map = []  # List of actual slide indices for final presentation\n    duplicated = {}  # Track duplicates: original_idx -> [duplicate_indices]\n\n    # Step 1: DUPLICATE repeated slides\n    print(f\"Processing {len(slide_sequence)} slides from template...\")\n    for i, template_idx in enumerate(slide_sequence):\n        if template_idx in duplicated and duplicated[template_idx]:\n            # Already duplicated this slide, use the duplicate\n            slide_map.append(duplicated[template_idx].pop(0))\n            print(f\"  [{i}] Using duplicate of slide {template_idx}\")\n        elif slide_sequence.count(template_idx) > 1 and template_idx not in duplicated:\n            # First occurrence of a repeated slide - create duplicates\n            slide_map.append(template_idx)\n            duplicates = []\n            count = slide_sequence.count(template_idx) - 1\n            print(\n                f\"  [{i}] Using original slide {template_idx}, creating {count} duplicate(s)\"\n            )\n            for _ in range(count):\n                duplicate_slide(prs, template_idx)\n                duplicates.append(len(prs.slides) - 1)\n            duplicated[template_idx] = duplicates\n        else:\n            # Unique slide or first occurrence already handled, use original\n            slide_map.append(template_idx)\n            print(f\"  [{i}] Using original slide {template_idx}\")\n\n    # Step 2: DELETE unwanted slides (work backwards)\n    slides_to_keep = set(slide_map)\n    print(f\"\\nDeleting {len(prs.slides) - len(slides_to_keep)} unused slides...\")\n    for i in range(len(prs.slides) - 1, -1, -1):\n        if i not in slides_to_keep:\n            delete_slide(prs, i)\n            # Update slide_map indices after deletion\n            slide_map = [idx - 1 if idx > i else idx for idx in slide_map]\n\n    # Step 3: REORDER to final sequence\n    print(f\"Reordering {len(slide_map)} slides to final sequence...\")\n    for target_pos in range(len(slide_map)):\n        # Find which slide should be at target_pos\n        current_pos = slide_map[target_pos]\n        if current_pos != target_pos:\n            reorder_slides(prs, current_pos, target_pos)\n            # Update slide_map: the move shifts other slides\n            for i in range(len(slide_map)):\n                if slide_map[i] > current_pos and slide_map[i] <= target_pos:\n                    slide_map[i] -= 1\n                elif slide_map[i] < current_pos and slide_map[i] >= target_pos:\n                    slide_map[i] += 1\n            slide_map[target_pos] = target_pos\n\n    # Save the presentation\n    prs.save(output_path)\n    print(f\"\\nSaved rearranged presentation to: {output_path}\")\n    print(f\"Final presentation has {len(prs.slides)} slides\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/pptx/scripts/replace.py",
    "content": "#!/usr/bin/env python3\n\"\"\"Apply text replacements to PowerPoint presentation.\n\nUsage:\n    python replace.py <input.pptx> <replacements.json> <output.pptx>\n\nThe replacements JSON should have the structure output by inventory.py.\nALL text shapes identified by inventory.py will have their text cleared\nunless \"paragraphs\" is specified in the replacements for that shape.\n\"\"\"\n\nimport json\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict, List\n\nfrom inventory import InventoryData, extract_text_inventory\nfrom pptx import Presentation\nfrom pptx.dml.color import RGBColor\nfrom pptx.enum.dml import MSO_THEME_COLOR\nfrom pptx.enum.text import PP_ALIGN\nfrom pptx.oxml.xmlchemy import OxmlElement\nfrom pptx.util import Pt\n\n\ndef clear_paragraph_bullets(paragraph):\n    \"\"\"Clear bullet formatting from a paragraph.\"\"\"\n    pPr = paragraph._element.get_or_add_pPr()\n\n    # Remove existing bullet elements\n    for child in list(pPr):\n        if (\n            child.tag.endswith(\"buChar\")\n            or child.tag.endswith(\"buNone\")\n            or child.tag.endswith(\"buAutoNum\")\n            or child.tag.endswith(\"buFont\")\n        ):\n            pPr.remove(child)\n\n    return pPr\n\n\ndef apply_paragraph_properties(paragraph, para_data: Dict[str, Any]):\n    \"\"\"Apply formatting properties to a paragraph.\"\"\"\n    # Get the text but don't set it on paragraph directly yet\n    text = para_data.get(\"text\", \"\")\n\n    # Get or create paragraph properties\n    pPr = clear_paragraph_bullets(paragraph)\n\n    # Handle bullet formatting\n    if para_data.get(\"bullet\", False):\n        level = para_data.get(\"level\", 0)\n        paragraph.level = level\n\n        # Calculate font-proportional indentation\n        font_size = para_data.get(\"font_size\", 18.0)\n        level_indent_emu = int((font_size * (1.6 + level * 1.6)) * 12700)\n        hanging_indent_emu = int(-font_size * 0.8 * 12700)\n\n        # Set indentation\n        pPr.attrib[\"marL\"] = str(level_indent_emu)\n        pPr.attrib[\"indent\"] = str(hanging_indent_emu)\n\n        # Add bullet character\n        buChar = OxmlElement(\"a:buChar\")\n        buChar.set(\"char\", \"•\")\n        pPr.append(buChar)\n\n        # Default to left alignment for bullets if not specified\n        if \"alignment\" not in para_data:\n            paragraph.alignment = PP_ALIGN.LEFT\n    else:\n        # Remove indentation for non-bullet text\n        pPr.attrib[\"marL\"] = \"0\"\n        pPr.attrib[\"indent\"] = \"0\"\n\n        # Add buNone element\n        buNone = OxmlElement(\"a:buNone\")\n        pPr.insert(0, buNone)\n\n    # Apply alignment\n    if \"alignment\" in para_data:\n        alignment_map = {\n            \"LEFT\": PP_ALIGN.LEFT,\n            \"CENTER\": PP_ALIGN.CENTER,\n            \"RIGHT\": PP_ALIGN.RIGHT,\n            \"JUSTIFY\": PP_ALIGN.JUSTIFY,\n        }\n        if para_data[\"alignment\"] in alignment_map:\n            paragraph.alignment = alignment_map[para_data[\"alignment\"]]\n\n    # Apply spacing\n    if \"space_before\" in para_data:\n        paragraph.space_before = Pt(para_data[\"space_before\"])\n    if \"space_after\" in para_data:\n        paragraph.space_after = Pt(para_data[\"space_after\"])\n    if \"line_spacing\" in para_data:\n        paragraph.line_spacing = Pt(para_data[\"line_spacing\"])\n\n    # Apply run-level formatting\n    if not paragraph.runs:\n        run = paragraph.add_run()\n        run.text = text\n    else:\n        run = paragraph.runs[0]\n        run.text = text\n\n    # Apply font properties\n    apply_font_properties(run, para_data)\n\n\ndef apply_font_properties(run, para_data: Dict[str, Any]):\n    \"\"\"Apply font properties to a text run.\"\"\"\n    if \"bold\" in para_data:\n        run.font.bold = para_data[\"bold\"]\n    if \"italic\" in para_data:\n        run.font.italic = para_data[\"italic\"]\n    if \"underline\" in para_data:\n        run.font.underline = para_data[\"underline\"]\n    if \"font_size\" in para_data:\n        run.font.size = Pt(para_data[\"font_size\"])\n    if \"font_name\" in para_data:\n        run.font.name = para_data[\"font_name\"]\n\n    # Apply color - prefer RGB, fall back to theme_color\n    if \"color\" in para_data:\n        color_hex = para_data[\"color\"].lstrip(\"#\")\n        if len(color_hex) == 6:\n            r = int(color_hex[0:2], 16)\n            g = int(color_hex[2:4], 16)\n            b = int(color_hex[4:6], 16)\n            run.font.color.rgb = RGBColor(r, g, b)\n    elif \"theme_color\" in para_data:\n        # Get theme color by name (e.g., \"DARK_1\", \"ACCENT_1\")\n        theme_name = para_data[\"theme_color\"]\n        try:\n            run.font.color.theme_color = getattr(MSO_THEME_COLOR, theme_name)\n        except AttributeError:\n            print(f\"  WARNING: Unknown theme color name '{theme_name}'\")\n\n\ndef detect_frame_overflow(inventory: InventoryData) -> Dict[str, Dict[str, float]]:\n    \"\"\"Detect text overflow in shapes (text exceeding shape bounds).\n\n    Returns dict of slide_key -> shape_key -> overflow_inches.\n    Only includes shapes that have text overflow.\n    \"\"\"\n    overflow_map = {}\n\n    for slide_key, shapes_dict in inventory.items():\n        for shape_key, shape_data in shapes_dict.items():\n            # Check for frame overflow (text exceeding shape bounds)\n            if shape_data.frame_overflow_bottom is not None:\n                if slide_key not in overflow_map:\n                    overflow_map[slide_key] = {}\n                overflow_map[slide_key][shape_key] = shape_data.frame_overflow_bottom\n\n    return overflow_map\n\n\ndef validate_replacements(inventory: InventoryData, replacements: Dict) -> List[str]:\n    \"\"\"Validate that all shapes in replacements exist in inventory.\n\n    Returns list of error messages.\n    \"\"\"\n    errors = []\n\n    for slide_key, shapes_data in replacements.items():\n        if not slide_key.startswith(\"slide-\"):\n            continue\n\n        # Check if slide exists\n        if slide_key not in inventory:\n            errors.append(f\"Slide '{slide_key}' not found in inventory\")\n            continue\n\n        # Check each shape\n        for shape_key in shapes_data.keys():\n            if shape_key not in inventory[slide_key]:\n                # Find shapes without replacements defined and show their content\n                unused_with_content = []\n                for k in inventory[slide_key].keys():\n                    if k not in shapes_data:\n                        shape_data = inventory[slide_key][k]\n                        # Get text from paragraphs as preview\n                        paragraphs = shape_data.paragraphs\n                        if paragraphs and paragraphs[0].text:\n                            first_text = paragraphs[0].text[:50]\n                            if len(paragraphs[0].text) > 50:\n                                first_text += \"...\"\n                            unused_with_content.append(f\"{k} ('{first_text}')\")\n                        else:\n                            unused_with_content.append(k)\n\n                errors.append(\n                    f\"Shape '{shape_key}' not found on '{slide_key}'. \"\n                    f\"Shapes without replacements: {', '.join(sorted(unused_with_content)) if unused_with_content else 'none'}\"\n                )\n\n    return errors\n\n\ndef check_duplicate_keys(pairs):\n    \"\"\"Check for duplicate keys when loading JSON.\"\"\"\n    result = {}\n    for key, value in pairs:\n        if key in result:\n            raise ValueError(f\"Duplicate key found in JSON: '{key}'\")\n        result[key] = value\n    return result\n\n\ndef apply_replacements(pptx_file: str, json_file: str, output_file: str):\n    \"\"\"Apply text replacements from JSON to PowerPoint presentation.\"\"\"\n\n    # Load presentation\n    prs = Presentation(pptx_file)\n\n    # Get inventory of all text shapes (returns ShapeData objects)\n    # Pass prs to use same Presentation instance\n    inventory = extract_text_inventory(Path(pptx_file), prs)\n\n    # Detect text overflow in original presentation\n    original_overflow = detect_frame_overflow(inventory)\n\n    # Load replacement data with duplicate key detection\n    with open(json_file, \"r\") as f:\n        replacements = json.load(f, object_pairs_hook=check_duplicate_keys)\n\n    # Validate replacements\n    errors = validate_replacements(inventory, replacements)\n    if errors:\n        print(\"ERROR: Invalid shapes in replacement JSON:\")\n        for error in errors:\n            print(f\"  - {error}\")\n        print(\"\\nPlease check the inventory and update your replacement JSON.\")\n        print(\n            \"You can regenerate the inventory with: python inventory.py <input.pptx> <output.json>\"\n        )\n        raise ValueError(f\"Found {len(errors)} validation error(s)\")\n\n    # Track statistics\n    shapes_processed = 0\n    shapes_cleared = 0\n    shapes_replaced = 0\n\n    # Process each slide from inventory\n    for slide_key, shapes_dict in inventory.items():\n        if not slide_key.startswith(\"slide-\"):\n            continue\n\n        slide_index = int(slide_key.split(\"-\")[1])\n\n        if slide_index >= len(prs.slides):\n            print(f\"Warning: Slide {slide_index} not found\")\n            continue\n\n        # Process each shape from inventory\n        for shape_key, shape_data in shapes_dict.items():\n            shapes_processed += 1\n\n            # Get the shape directly from ShapeData\n            shape = shape_data.shape\n            if not shape:\n                print(f\"Warning: {shape_key} has no shape reference\")\n                continue\n\n            # ShapeData already validates text_frame in __init__\n            text_frame = shape.text_frame  # type: ignore\n\n            text_frame.clear()  # type: ignore\n            shapes_cleared += 1\n\n            # Check for replacement paragraphs\n            replacement_shape_data = replacements.get(slide_key, {}).get(shape_key, {})\n            if \"paragraphs\" not in replacement_shape_data:\n                continue\n\n            shapes_replaced += 1\n\n            # Add replacement paragraphs\n            for i, para_data in enumerate(replacement_shape_data[\"paragraphs\"]):\n                if i == 0:\n                    p = text_frame.paragraphs[0]  # type: ignore\n                else:\n                    p = text_frame.add_paragraph()  # type: ignore\n\n                apply_paragraph_properties(p, para_data)\n\n    # Check for issues after replacements\n    # Save to a temporary file and reload to avoid modifying the presentation during inventory\n    # (extract_text_inventory accesses font.color which adds empty <a:solidFill/> elements)\n    import tempfile\n\n    with tempfile.NamedTemporaryFile(suffix=\".pptx\", delete=False) as tmp:\n        tmp_path = Path(tmp.name)\n        prs.save(str(tmp_path))\n\n    try:\n        updated_inventory = extract_text_inventory(tmp_path)\n        updated_overflow = detect_frame_overflow(updated_inventory)\n    finally:\n        tmp_path.unlink()  # Clean up temp file\n\n    # Check if any text overflow got worse\n    overflow_errors = []\n    for slide_key, shape_overflows in updated_overflow.items():\n        for shape_key, new_overflow in shape_overflows.items():\n            # Get original overflow (0 if there was no overflow before)\n            original = original_overflow.get(slide_key, {}).get(shape_key, 0.0)\n\n            # Error if overflow increased\n            if new_overflow > original + 0.01:  # Small tolerance for rounding\n                increase = new_overflow - original\n                overflow_errors.append(\n                    f'{slide_key}/{shape_key}: overflow worsened by {increase:.2f}\" '\n                    f'(was {original:.2f}\", now {new_overflow:.2f}\")'\n                )\n\n    # Collect warnings from updated shapes\n    warnings = []\n    for slide_key, shapes_dict in updated_inventory.items():\n        for shape_key, shape_data in shapes_dict.items():\n            if shape_data.warnings:\n                for warning in shape_data.warnings:\n                    warnings.append(f\"{slide_key}/{shape_key}: {warning}\")\n\n    # Fail if there are any issues\n    if overflow_errors or warnings:\n        print(\"\\nERROR: Issues detected in replacement output:\")\n        if overflow_errors:\n            print(\"\\nText overflow worsened:\")\n            for error in overflow_errors:\n                print(f\"  - {error}\")\n        if warnings:\n            print(\"\\nFormatting warnings:\")\n            for warning in warnings:\n                print(f\"  - {warning}\")\n        print(\"\\nPlease fix these issues before saving.\")\n        raise ValueError(\n            f\"Found {len(overflow_errors)} overflow error(s) and {len(warnings)} warning(s)\"\n        )\n\n    # Save the presentation\n    prs.save(output_file)\n\n    # Report results\n    print(f\"Saved updated presentation to: {output_file}\")\n    print(f\"Processed {len(prs.slides)} slides\")\n    print(f\"  - Shapes processed: {shapes_processed}\")\n    print(f\"  - Shapes cleared: {shapes_cleared}\")\n    print(f\"  - Shapes replaced: {shapes_replaced}\")\n\n\ndef main():\n    \"\"\"Main entry point for command-line usage.\"\"\"\n    if len(sys.argv) != 4:\n        print(__doc__)\n        sys.exit(1)\n\n    input_pptx = Path(sys.argv[1])\n    replacements_json = Path(sys.argv[2])\n    output_pptx = Path(sys.argv[3])\n\n    if not input_pptx.exists():\n        print(f\"Error: Input file '{input_pptx}' not found\")\n        sys.exit(1)\n\n    if not replacements_json.exists():\n        print(f\"Error: Replacements JSON file '{replacements_json}' not found\")\n        sys.exit(1)\n\n    try:\n        apply_replacements(str(input_pptx), str(replacements_json), str(output_pptx))\n    except Exception as e:\n        print(f\"Error applying replacements: {e}\")\n        import traceback\n\n        traceback.print_exc()\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/pptx/scripts/thumbnail.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nCreate thumbnail grids from PowerPoint presentation slides.\n\nCreates a grid layout of slide thumbnails with configurable columns (max 6).\nEach grid contains up to cols×(cols+1) images. For presentations with more\nslides, multiple numbered grid files are created automatically.\n\nThe program outputs the names of all files created.\n\nOutput:\n- Single grid: {prefix}.jpg (if slides fit in one grid)\n- Multiple grids: {prefix}-1.jpg, {prefix}-2.jpg, etc.\n\nGrid limits by column count:\n- 3 cols: max 12 slides per grid (3×4)\n- 4 cols: max 20 slides per grid (4×5)\n- 5 cols: max 30 slides per grid (5×6) [default]\n- 6 cols: max 42 slides per grid (6×7)\n\nUsage:\n    python thumbnail.py input.pptx [output_prefix] [--cols N] [--outline-placeholders]\n\nExamples:\n    python thumbnail.py presentation.pptx\n    # Creates: thumbnails.jpg (using default prefix)\n    # Outputs:\n    #   Created 1 grid(s):\n    #     - thumbnails.jpg\n\n    python thumbnail.py large-deck.pptx grid --cols 4\n    # Creates: grid-1.jpg, grid-2.jpg, grid-3.jpg\n    # Outputs:\n    #   Created 3 grid(s):\n    #     - grid-1.jpg\n    #     - grid-2.jpg\n    #     - grid-3.jpg\n\n    python thumbnail.py template.pptx analysis --outline-placeholders\n    # Creates thumbnail grids with red outlines around text placeholders\n\"\"\"\n\nimport argparse\nimport subprocess\nimport sys\nimport tempfile\nfrom pathlib import Path\n\nfrom inventory import extract_text_inventory\nfrom PIL import Image, ImageDraw, ImageFont\nfrom pptx import Presentation\n\n# Constants\nTHUMBNAIL_WIDTH = 300  # Fixed thumbnail width in pixels\nCONVERSION_DPI = 100  # DPI for PDF to image conversion\nMAX_COLS = 6  # Maximum number of columns\nDEFAULT_COLS = 5  # Default number of columns\nJPEG_QUALITY = 95  # JPEG compression quality\n\n# Grid layout constants\nGRID_PADDING = 20  # Padding between thumbnails\nBORDER_WIDTH = 2  # Border width around thumbnails\nFONT_SIZE_RATIO = 0.12  # Font size as fraction of thumbnail width\nLABEL_PADDING_RATIO = 0.4  # Label padding as fraction of font size\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description=\"Create thumbnail grids from PowerPoint slides.\"\n    )\n    parser.add_argument(\"input\", help=\"Input PowerPoint file (.pptx)\")\n    parser.add_argument(\n        \"output_prefix\",\n        nargs=\"?\",\n        default=\"thumbnails\",\n        help=\"Output prefix for image files (default: thumbnails, will create prefix.jpg or prefix-N.jpg)\",\n    )\n    parser.add_argument(\n        \"--cols\",\n        type=int,\n        default=DEFAULT_COLS,\n        help=f\"Number of columns (default: {DEFAULT_COLS}, max: {MAX_COLS})\",\n    )\n    parser.add_argument(\n        \"--outline-placeholders\",\n        action=\"store_true\",\n        help=\"Outline text placeholders with a colored border\",\n    )\n\n    args = parser.parse_args()\n\n    # Validate columns\n    cols = min(args.cols, MAX_COLS)\n    if args.cols > MAX_COLS:\n        print(f\"Warning: Columns limited to {MAX_COLS} (requested {args.cols})\")\n\n    # Validate input\n    input_path = Path(args.input)\n    if not input_path.exists() or input_path.suffix.lower() != \".pptx\":\n        print(f\"Error: Invalid PowerPoint file: {args.input}\")\n        sys.exit(1)\n\n    # Construct output path (always JPG)\n    output_path = Path(f\"{args.output_prefix}.jpg\")\n\n    print(f\"Processing: {args.input}\")\n\n    try:\n        with tempfile.TemporaryDirectory() as temp_dir:\n            # Get placeholder regions if outlining is enabled\n            placeholder_regions = None\n            slide_dimensions = None\n            if args.outline_placeholders:\n                print(\"Extracting placeholder regions...\")\n                placeholder_regions, slide_dimensions = get_placeholder_regions(\n                    input_path\n                )\n                if placeholder_regions:\n                    print(f\"Found placeholders on {len(placeholder_regions)} slides\")\n\n            # Convert slides to images\n            slide_images = convert_to_images(input_path, Path(temp_dir), CONVERSION_DPI)\n            if not slide_images:\n                print(\"Error: No slides found\")\n                sys.exit(1)\n\n            print(f\"Found {len(slide_images)} slides\")\n\n            # Create grids (max cols×(cols+1) images per grid)\n            grid_files = create_grids(\n                slide_images,\n                cols,\n                THUMBNAIL_WIDTH,\n                output_path,\n                placeholder_regions,\n                slide_dimensions,\n            )\n\n            # Print saved files\n            print(f\"Created {len(grid_files)} grid(s):\")\n            for grid_file in grid_files:\n                print(f\"  - {grid_file}\")\n\n    except Exception as e:\n        print(f\"Error: {e}\")\n        sys.exit(1)\n\n\ndef create_hidden_slide_placeholder(size):\n    \"\"\"Create placeholder image for hidden slides.\"\"\"\n    img = Image.new(\"RGB\", size, color=\"#F0F0F0\")\n    draw = ImageDraw.Draw(img)\n    line_width = max(5, min(size) // 100)\n    draw.line([(0, 0), size], fill=\"#CCCCCC\", width=line_width)\n    draw.line([(size[0], 0), (0, size[1])], fill=\"#CCCCCC\", width=line_width)\n    return img\n\n\ndef get_placeholder_regions(pptx_path):\n    \"\"\"Extract ALL text regions from the presentation.\n\n    Returns a tuple of (placeholder_regions, slide_dimensions).\n    text_regions is a dict mapping slide indices to lists of text regions.\n    Each region is a dict with 'left', 'top', 'width', 'height' in inches.\n    slide_dimensions is a tuple of (width_inches, height_inches).\n    \"\"\"\n    prs = Presentation(str(pptx_path))\n    inventory = extract_text_inventory(pptx_path, prs)\n    placeholder_regions = {}\n\n    # Get actual slide dimensions in inches (EMU to inches conversion)\n    slide_width_inches = (prs.slide_width or 9144000) / 914400.0\n    slide_height_inches = (prs.slide_height or 5143500) / 914400.0\n\n    for slide_key, shapes in inventory.items():\n        # Extract slide index from \"slide-N\" format\n        slide_idx = int(slide_key.split(\"-\")[1])\n        regions = []\n\n        for shape_key, shape_data in shapes.items():\n            # The inventory only contains shapes with text, so all shapes should be highlighted\n            regions.append(\n                {\n                    \"left\": shape_data.left,\n                    \"top\": shape_data.top,\n                    \"width\": shape_data.width,\n                    \"height\": shape_data.height,\n                }\n            )\n\n        if regions:\n            placeholder_regions[slide_idx] = regions\n\n    return placeholder_regions, (slide_width_inches, slide_height_inches)\n\n\ndef convert_to_images(pptx_path, temp_dir, dpi):\n    \"\"\"Convert PowerPoint to images via PDF, handling hidden slides.\"\"\"\n    # Detect hidden slides\n    print(\"Analyzing presentation...\")\n    prs = Presentation(str(pptx_path))\n    total_slides = len(prs.slides)\n\n    # Find hidden slides (1-based indexing for display)\n    hidden_slides = {\n        idx + 1\n        for idx, slide in enumerate(prs.slides)\n        if slide.element.get(\"show\") == \"0\"\n    }\n\n    print(f\"Total slides: {total_slides}\")\n    if hidden_slides:\n        print(f\"Hidden slides: {sorted(hidden_slides)}\")\n\n    pdf_path = temp_dir / f\"{pptx_path.stem}.pdf\"\n\n    # Convert to PDF\n    print(\"Converting to PDF...\")\n    result = subprocess.run(\n        [\n            \"soffice\",\n            \"--headless\",\n            \"--convert-to\",\n            \"pdf\",\n            \"--outdir\",\n            str(temp_dir),\n            str(pptx_path),\n        ],\n        capture_output=True,\n        text=True,\n    )\n    if result.returncode != 0 or not pdf_path.exists():\n        raise RuntimeError(\"PDF conversion failed\")\n\n    # Convert PDF to images\n    print(f\"Converting to images at {dpi} DPI...\")\n    result = subprocess.run(\n        [\"pdftoppm\", \"-jpeg\", \"-r\", str(dpi), str(pdf_path), str(temp_dir / \"slide\")],\n        capture_output=True,\n        text=True,\n    )\n    if result.returncode != 0:\n        raise RuntimeError(\"Image conversion failed\")\n\n    visible_images = sorted(temp_dir.glob(\"slide-*.jpg\"))\n\n    # Create full list with placeholders for hidden slides\n    all_images = []\n    visible_idx = 0\n\n    # Get placeholder dimensions from first visible slide\n    if visible_images:\n        with Image.open(visible_images[0]) as img:\n            placeholder_size = img.size\n    else:\n        placeholder_size = (1920, 1080)\n\n    for slide_num in range(1, total_slides + 1):\n        if slide_num in hidden_slides:\n            # Create placeholder image for hidden slide\n            placeholder_path = temp_dir / f\"hidden-{slide_num:03d}.jpg\"\n            placeholder_img = create_hidden_slide_placeholder(placeholder_size)\n            placeholder_img.save(placeholder_path, \"JPEG\")\n            all_images.append(placeholder_path)\n        else:\n            # Use the actual visible slide image\n            if visible_idx < len(visible_images):\n                all_images.append(visible_images[visible_idx])\n                visible_idx += 1\n\n    return all_images\n\n\ndef create_grids(\n    image_paths,\n    cols,\n    width,\n    output_path,\n    placeholder_regions=None,\n    slide_dimensions=None,\n):\n    \"\"\"Create multiple thumbnail grids from slide images, max cols×(cols+1) images per grid.\"\"\"\n    # Maximum images per grid is cols × (cols + 1) for better proportions\n    max_images_per_grid = cols * (cols + 1)\n    grid_files = []\n\n    print(\n        f\"Creating grids with {cols} columns (max {max_images_per_grid} images per grid)\"\n    )\n\n    # Split images into chunks\n    for chunk_idx, start_idx in enumerate(\n        range(0, len(image_paths), max_images_per_grid)\n    ):\n        end_idx = min(start_idx + max_images_per_grid, len(image_paths))\n        chunk_images = image_paths[start_idx:end_idx]\n\n        # Create grid for this chunk\n        grid = create_grid(\n            chunk_images, cols, width, start_idx, placeholder_regions, slide_dimensions\n        )\n\n        # Generate output filename\n        if len(image_paths) <= max_images_per_grid:\n            # Single grid - use base filename without suffix\n            grid_filename = output_path\n        else:\n            # Multiple grids - insert index before extension with dash\n            stem = output_path.stem\n            suffix = output_path.suffix\n            grid_filename = output_path.parent / f\"{stem}-{chunk_idx + 1}{suffix}\"\n\n        # Save grid\n        grid_filename.parent.mkdir(parents=True, exist_ok=True)\n        grid.save(str(grid_filename), quality=JPEG_QUALITY)\n        grid_files.append(str(grid_filename))\n\n    return grid_files\n\n\ndef create_grid(\n    image_paths,\n    cols,\n    width,\n    start_slide_num=0,\n    placeholder_regions=None,\n    slide_dimensions=None,\n):\n    \"\"\"Create thumbnail grid from slide images with optional placeholder outlining.\"\"\"\n    font_size = int(width * FONT_SIZE_RATIO)\n    label_padding = int(font_size * LABEL_PADDING_RATIO)\n\n    # Get dimensions\n    with Image.open(image_paths[0]) as img:\n        aspect = img.height / img.width\n    height = int(width * aspect)\n\n    # Calculate grid size\n    rows = (len(image_paths) + cols - 1) // cols\n    grid_w = cols * width + (cols + 1) * GRID_PADDING\n    grid_h = rows * (height + font_size + label_padding * 2) + (rows + 1) * GRID_PADDING\n\n    # Create grid\n    grid = Image.new(\"RGB\", (grid_w, grid_h), \"white\")\n    draw = ImageDraw.Draw(grid)\n\n    # Load font with size based on thumbnail width\n    try:\n        # Use Pillow's default font with size\n        font = ImageFont.load_default(size=font_size)\n    except Exception:\n        # Fall back to basic default font if size parameter not supported\n        font = ImageFont.load_default()\n\n    # Place thumbnails\n    for i, img_path in enumerate(image_paths):\n        row, col = i // cols, i % cols\n        x = col * width + (col + 1) * GRID_PADDING\n        y_base = (\n            row * (height + font_size + label_padding * 2) + (row + 1) * GRID_PADDING\n        )\n\n        # Add label with actual slide number\n        label = f\"{start_slide_num + i}\"\n        bbox = draw.textbbox((0, 0), label, font=font)\n        text_w = bbox[2] - bbox[0]\n        draw.text(\n            (x + (width - text_w) // 2, y_base + label_padding),\n            label,\n            fill=\"black\",\n            font=font,\n        )\n\n        # Add thumbnail below label with proportional spacing\n        y_thumbnail = y_base + label_padding + font_size + label_padding\n\n        with Image.open(img_path) as img:\n            # Get original dimensions before thumbnail\n            orig_w, orig_h = img.size\n\n            # Apply placeholder outlines if enabled\n            if placeholder_regions and (start_slide_num + i) in placeholder_regions:\n                # Convert to RGBA for transparency support\n                if img.mode != \"RGBA\":\n                    img = img.convert(\"RGBA\")\n\n                # Get the regions for this slide\n                regions = placeholder_regions[start_slide_num + i]\n\n                # Calculate scale factors using actual slide dimensions\n                if slide_dimensions:\n                    slide_width_inches, slide_height_inches = slide_dimensions\n                else:\n                    # Fallback: estimate from image size at CONVERSION_DPI\n                    slide_width_inches = orig_w / CONVERSION_DPI\n                    slide_height_inches = orig_h / CONVERSION_DPI\n\n                x_scale = orig_w / slide_width_inches\n                y_scale = orig_h / slide_height_inches\n\n                # Create a highlight overlay\n                overlay = Image.new(\"RGBA\", img.size, (255, 255, 255, 0))\n                overlay_draw = ImageDraw.Draw(overlay)\n\n                # Highlight each placeholder region\n                for region in regions:\n                    # Convert from inches to pixels in the original image\n                    px_left = int(region[\"left\"] * x_scale)\n                    px_top = int(region[\"top\"] * y_scale)\n                    px_width = int(region[\"width\"] * x_scale)\n                    px_height = int(region[\"height\"] * y_scale)\n\n                    # Draw highlight outline with red color and thick stroke\n                    # Using a bright red outline instead of fill\n                    stroke_width = max(\n                        5, min(orig_w, orig_h) // 150\n                    )  # Thicker proportional stroke width\n                    overlay_draw.rectangle(\n                        [(px_left, px_top), (px_left + px_width, px_top + px_height)],\n                        outline=(255, 0, 0, 255),  # Bright red, fully opaque\n                        width=stroke_width,\n                    )\n\n                # Composite the overlay onto the image using alpha blending\n                img = Image.alpha_composite(img, overlay)\n                # Convert back to RGB for JPEG saving\n                img = img.convert(\"RGB\")\n\n            img.thumbnail((width, height), Image.Resampling.LANCZOS)\n            w, h = img.size\n            tx = x + (width - w) // 2\n            ty = y_thumbnail + (height - h) // 2\n            grid.paste(img, (tx, ty))\n\n            # Add border\n            if BORDER_WIDTH > 0:\n                draw.rectangle(\n                    [\n                        (tx - BORDER_WIDTH, ty - BORDER_WIDTH),\n                        (tx + w + BORDER_WIDTH - 1, ty + h + BORDER_WIDTH - 1),\n                    ],\n                    outline=\"gray\",\n                    width=BORDER_WIDTH,\n                )\n\n    return grid\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "document-skills/xlsx/LICENSE.txt",
    "content": "© 2025 Anthropic, PBC. All rights reserved.\n\nLICENSE: Use of these materials (including all code, prompts, assets, files,\nand other components of this Skill) is governed by your agreement with\nAnthropic regarding use of Anthropic's services. If no separate agreement\nexists, use is governed by Anthropic's Consumer Terms of Service or\nCommercial Terms of Service, as applicable:\nhttps://www.anthropic.com/legal/consumer-terms\nhttps://www.anthropic.com/legal/commercial-terms\nYour applicable agreement is referred to as the \"Agreement.\" \"Services\" are\nas defined in the Agreement.\n\nADDITIONAL RESTRICTIONS: Notwithstanding anything in the Agreement to the\ncontrary, users may not:\n\n- Extract these materials from the Services or retain copies of these\n  materials outside the Services\n- Reproduce or copy these materials, except for temporary copies created\n  automatically during authorized use of the Services\n- Create derivative works based on these materials\n- Distribute, sublicense, or transfer these materials to any third party\n- Make, offer to sell, sell, or import any inventions embodied in these\n  materials\n- Reverse engineer, decompile, or disassemble these materials\n\nThe receipt, viewing, or possession of these materials does not convey or\nimply any license or right beyond those expressly granted above.\n\nAnthropic retains all right, title, and interest in these materials,\nincluding all copyrights, patents, and other intellectual property rights.\n"
  },
  {
    "path": "document-skills/xlsx/SKILL.md",
    "content": "---\nname: xlsx\ndescription: \"Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas\"\nlicense: Proprietary. LICENSE.txt has complete terms\n---\n\n# Requirements for Outputs\n\n## All Excel files\n\n### Zero Formula Errors\n- Every Excel model MUST be delivered with ZERO formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)\n\n### Preserve Existing Templates (when updating templates)\n- Study and EXACTLY match existing format, style, and conventions when modifying files\n- Never impose standardized formatting on files with established patterns\n- Existing template conventions ALWAYS override these guidelines\n\n## Financial models\n\n### Color Coding Standards\nUnless otherwise stated by the user or existing template\n\n#### Industry-Standard Color Conventions\n- **Blue text (RGB: 0,0,255)**: Hardcoded inputs, and numbers users will change for scenarios\n- **Black text (RGB: 0,0,0)**: ALL formulas and calculations\n- **Green text (RGB: 0,128,0)**: Links pulling from other worksheets within same workbook\n- **Red text (RGB: 255,0,0)**: External links to other files\n- **Yellow background (RGB: 255,255,0)**: Key assumptions needing attention or cells that need to be updated\n\n### Number Formatting Standards\n\n#### Required Format Rules\n- **Years**: Format as text strings (e.g., \"2024\" not \"2,024\")\n- **Currency**: Use $#,##0 format; ALWAYS specify units in headers (\"Revenue ($mm)\")\n- **Zeros**: Use number formatting to make all zeros \"-\", including percentages (e.g., \"$#,##0;($#,##0);-\")\n- **Percentages**: Default to 0.0% format (one decimal)\n- **Multiples**: Format as 0.0x for valuation multiples (EV/EBITDA, P/E)\n- **Negative numbers**: Use parentheses (123) not minus -123\n\n### Formula Construction Rules\n\n#### Assumptions Placement\n- Place ALL assumptions (growth rates, margins, multiples, etc.) in separate assumption cells\n- Use cell references instead of hardcoded values in formulas\n- Example: Use =B5*(1+$B$6) instead of =B5*1.05\n\n#### Formula Error Prevention\n- Verify all cell references are correct\n- Check for off-by-one errors in ranges\n- Ensure consistent formulas across all projection periods\n- Test with edge cases (zero values, negative numbers)\n- Verify no unintended circular references\n\n#### Documentation Requirements for Hardcodes\n- Comment or in cells beside (if end of table). Format: \"Source: [System/Document], [Date], [Specific Reference], [URL if applicable]\"\n- Examples:\n  - \"Source: Company 10-K, FY2024, Page 45, Revenue Note, [SEC EDGAR URL]\"\n  - \"Source: Company 10-Q, Q2 2025, Exhibit 99.1, [SEC EDGAR URL]\"\n  - \"Source: Bloomberg Terminal, 8/15/2025, AAPL US Equity\"\n  - \"Source: FactSet, 8/20/2025, Consensus Estimates Screen\"\n\n# XLSX creation, editing, and analysis\n\n## Overview\n\nA user may ask you to create, edit, or analyze the contents of an .xlsx file. You have different tools and workflows available for different tasks.\n\n## Important Requirements\n\n**LibreOffice Required for Formula Recalculation**: You can assume LibreOffice is installed for recalculating formula values using the `recalc.py` script. The script automatically configures LibreOffice on first run\n\n## Reading and analyzing data\n\n### Data analysis with pandas\nFor data analysis, visualization, and basic operations, use **pandas** which provides powerful data manipulation capabilities:\n\n```python\nimport pandas as pd\n\n# Read Excel\ndf = pd.read_excel('file.xlsx')  # Default: first sheet\nall_sheets = pd.read_excel('file.xlsx', sheet_name=None)  # All sheets as dict\n\n# Analyze\ndf.head()      # Preview data\ndf.info()      # Column info\ndf.describe()  # Statistics\n\n# Write Excel\ndf.to_excel('output.xlsx', index=False)\n```\n\n## Excel File Workflows\n\n## CRITICAL: Use Formulas, Not Hardcoded Values\n\n**Always use Excel formulas instead of calculating values in Python and hardcoding them.** This ensures the spreadsheet remains dynamic and updateable.\n\n### ❌ WRONG - Hardcoding Calculated Values\n```python\n# Bad: Calculating in Python and hardcoding result\ntotal = df['Sales'].sum()\nsheet['B10'] = total  # Hardcodes 5000\n\n# Bad: Computing growth rate in Python\ngrowth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']\nsheet['C5'] = growth  # Hardcodes 0.15\n\n# Bad: Python calculation for average\navg = sum(values) / len(values)\nsheet['D20'] = avg  # Hardcodes 42.5\n```\n\n### ✅ CORRECT - Using Excel Formulas\n```python\n# Good: Let Excel calculate the sum\nsheet['B10'] = '=SUM(B2:B9)'\n\n# Good: Growth rate as Excel formula\nsheet['C5'] = '=(C4-C2)/C2'\n\n# Good: Average using Excel function\nsheet['D20'] = '=AVERAGE(D2:D19)'\n```\n\nThis applies to ALL calculations - totals, percentages, ratios, differences, etc. The spreadsheet should be able to recalculate when source data changes.\n\n## Common Workflow\n1. **Choose tool**: pandas for data, openpyxl for formulas/formatting\n2. **Create/Load**: Create new workbook or load existing file\n3. **Modify**: Add/edit data, formulas, and formatting\n4. **Save**: Write to file\n5. **Recalculate formulas (MANDATORY IF USING FORMULAS)**: Use the recalc.py script\n   ```bash\n   python recalc.py output.xlsx\n   ```\n6. **Verify and fix any errors**: \n   - The script returns JSON with error details\n   - If `status` is `errors_found`, check `error_summary` for specific error types and locations\n   - Fix the identified errors and recalculate again\n   - Common errors to fix:\n     - `#REF!`: Invalid cell references\n     - `#DIV/0!`: Division by zero\n     - `#VALUE!`: Wrong data type in formula\n     - `#NAME?`: Unrecognized formula name\n\n### Creating new Excel files\n\n```python\n# Using openpyxl for formulas and formatting\nfrom openpyxl import Workbook\nfrom openpyxl.styles import Font, PatternFill, Alignment\n\nwb = Workbook()\nsheet = wb.active\n\n# Add data\nsheet['A1'] = 'Hello'\nsheet['B1'] = 'World'\nsheet.append(['Row', 'of', 'data'])\n\n# Add formula\nsheet['B2'] = '=SUM(A1:A10)'\n\n# Formatting\nsheet['A1'].font = Font(bold=True, color='FF0000')\nsheet['A1'].fill = PatternFill('solid', start_color='FFFF00')\nsheet['A1'].alignment = Alignment(horizontal='center')\n\n# Column width\nsheet.column_dimensions['A'].width = 20\n\nwb.save('output.xlsx')\n```\n\n### Editing existing Excel files\n\n```python\n# Using openpyxl to preserve formulas and formatting\nfrom openpyxl import load_workbook\n\n# Load existing file\nwb = load_workbook('existing.xlsx')\nsheet = wb.active  # or wb['SheetName'] for specific sheet\n\n# Working with multiple sheets\nfor sheet_name in wb.sheetnames:\n    sheet = wb[sheet_name]\n    print(f\"Sheet: {sheet_name}\")\n\n# Modify cells\nsheet['A1'] = 'New Value'\nsheet.insert_rows(2)  # Insert row at position 2\nsheet.delete_cols(3)  # Delete column 3\n\n# Add new sheet\nnew_sheet = wb.create_sheet('NewSheet')\nnew_sheet['A1'] = 'Data'\n\nwb.save('modified.xlsx')\n```\n\n## Recalculating formulas\n\nExcel files created or modified by openpyxl contain formulas as strings but not calculated values. Use the provided `recalc.py` script to recalculate formulas:\n\n```bash\npython recalc.py <excel_file> [timeout_seconds]\n```\n\nExample:\n```bash\npython recalc.py output.xlsx 30\n```\n\nThe script:\n- Automatically sets up LibreOffice macro on first run\n- Recalculates all formulas in all sheets\n- Scans ALL cells for Excel errors (#REF!, #DIV/0!, etc.)\n- Returns JSON with detailed error locations and counts\n- Works on both Linux and macOS\n\n## Formula Verification Checklist\n\nQuick checks to ensure formulas work correctly:\n\n### Essential Verification\n- [ ] **Test 2-3 sample references**: Verify they pull correct values before building full model\n- [ ] **Column mapping**: Confirm Excel columns match (e.g., column 64 = BL, not BK)\n- [ ] **Row offset**: Remember Excel rows are 1-indexed (DataFrame row 5 = Excel row 6)\n\n### Common Pitfalls\n- [ ] **NaN handling**: Check for null values with `pd.notna()`\n- [ ] **Far-right columns**: FY data often in columns 50+ \n- [ ] **Multiple matches**: Search all occurrences, not just first\n- [ ] **Division by zero**: Check denominators before using `/` in formulas (#DIV/0!)\n- [ ] **Wrong references**: Verify all cell references point to intended cells (#REF!)\n- [ ] **Cross-sheet references**: Use correct format (Sheet1!A1) for linking sheets\n\n### Formula Testing Strategy\n- [ ] **Start small**: Test formulas on 2-3 cells before applying broadly\n- [ ] **Verify dependencies**: Check all cells referenced in formulas exist\n- [ ] **Test edge cases**: Include zero, negative, and very large values\n\n### Interpreting recalc.py Output\nThe script returns JSON with error details:\n```json\n{\n  \"status\": \"success\",           // or \"errors_found\"\n  \"total_errors\": 0,              // Total error count\n  \"total_formulas\": 42,           // Number of formulas in file\n  \"error_summary\": {              // Only present if errors found\n    \"#REF!\": {\n      \"count\": 2,\n      \"locations\": [\"Sheet1!B5\", \"Sheet1!C10\"]\n    }\n  }\n}\n```\n\n## Best Practices\n\n### Library Selection\n- **pandas**: Best for data analysis, bulk operations, and simple data export\n- **openpyxl**: Best for complex formatting, formulas, and Excel-specific features\n\n### Working with openpyxl\n- Cell indices are 1-based (row=1, column=1 refers to cell A1)\n- Use `data_only=True` to read calculated values: `load_workbook('file.xlsx', data_only=True)`\n- **Warning**: If opened with `data_only=True` and saved, formulas are replaced with values and permanently lost\n- For large files: Use `read_only=True` for reading or `write_only=True` for writing\n- Formulas are preserved but not evaluated - use recalc.py to update values\n\n### Working with pandas\n- Specify data types to avoid inference issues: `pd.read_excel('file.xlsx', dtype={'id': str})`\n- For large files, read specific columns: `pd.read_excel('file.xlsx', usecols=['A', 'C', 'E'])`\n- Handle dates properly: `pd.read_excel('file.xlsx', parse_dates=['date_column'])`\n\n## Code Style Guidelines\n**IMPORTANT**: When generating Python code for Excel operations:\n- Write minimal, concise Python code without unnecessary comments\n- Avoid verbose variable names and redundant operations\n- Avoid unnecessary print statements\n\n**For Excel files themselves**:\n- Add comments to cells with complex formulas or important assumptions\n- Document data sources for hardcoded values\n- Include notes for key calculations and model sections"
  },
  {
    "path": "document-skills/xlsx/recalc.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nExcel Formula Recalculation Script\nRecalculates all formulas in an Excel file using LibreOffice\n\"\"\"\n\nimport json\nimport sys\nimport subprocess\nimport os\nimport platform\nfrom pathlib import Path\nfrom openpyxl import load_workbook\n\n\ndef setup_libreoffice_macro():\n    \"\"\"Setup LibreOffice macro for recalculation if not already configured\"\"\"\n    if platform.system() == 'Darwin':\n        macro_dir = os.path.expanduser('~/Library/Application Support/LibreOffice/4/user/basic/Standard')\n    else:\n        macro_dir = os.path.expanduser('~/.config/libreoffice/4/user/basic/Standard')\n    \n    macro_file = os.path.join(macro_dir, 'Module1.xba')\n    \n    if os.path.exists(macro_file):\n        with open(macro_file, 'r') as f:\n            if 'RecalculateAndSave' in f.read():\n                return True\n    \n    if not os.path.exists(macro_dir):\n        subprocess.run(['soffice', '--headless', '--terminate_after_init'], \n                      capture_output=True, timeout=10)\n        os.makedirs(macro_dir, exist_ok=True)\n    \n    macro_content = '''<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE script:module PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"module.dtd\">\n<script:module xmlns:script=\"http://openoffice.org/2000/script\" script:name=\"Module1\" script:language=\"StarBasic\">\n    Sub RecalculateAndSave()\n      ThisComponent.calculateAll()\n      ThisComponent.store()\n      ThisComponent.close(True)\n    End Sub\n</script:module>'''\n    \n    try:\n        with open(macro_file, 'w') as f:\n            f.write(macro_content)\n        return True\n    except Exception:\n        return False\n\n\ndef recalc(filename, timeout=30):\n    \"\"\"\n    Recalculate formulas in Excel file and report any errors\n    \n    Args:\n        filename: Path to Excel file\n        timeout: Maximum time to wait for recalculation (seconds)\n    \n    Returns:\n        dict with error locations and counts\n    \"\"\"\n    if not Path(filename).exists():\n        return {'error': f'File {filename} does not exist'}\n    \n    abs_path = str(Path(filename).absolute())\n    \n    if not setup_libreoffice_macro():\n        return {'error': 'Failed to setup LibreOffice macro'}\n    \n    cmd = [\n        'soffice', '--headless', '--norestore',\n        'vnd.sun.star.script:Standard.Module1.RecalculateAndSave?language=Basic&location=application',\n        abs_path\n    ]\n    \n    # Handle timeout command differences between Linux and macOS\n    if platform.system() != 'Windows':\n        timeout_cmd = 'timeout' if platform.system() == 'Linux' else None\n        if platform.system() == 'Darwin':\n            # Check if gtimeout is available on macOS\n            try:\n                subprocess.run(['gtimeout', '--version'], capture_output=True, timeout=1, check=False)\n                timeout_cmd = 'gtimeout'\n            except (FileNotFoundError, subprocess.TimeoutExpired):\n                pass\n        \n        if timeout_cmd:\n            cmd = [timeout_cmd, str(timeout)] + cmd\n    \n    result = subprocess.run(cmd, capture_output=True, text=True)\n    \n    if result.returncode != 0 and result.returncode != 124:  # 124 is timeout exit code\n        error_msg = result.stderr or 'Unknown error during recalculation'\n        if 'Module1' in error_msg or 'RecalculateAndSave' not in error_msg:\n            return {'error': 'LibreOffice macro not configured properly'}\n        else:\n            return {'error': error_msg}\n    \n    # Check for Excel errors in the recalculated file - scan ALL cells\n    try:\n        wb = load_workbook(filename, data_only=True)\n        \n        excel_errors = ['#VALUE!', '#DIV/0!', '#REF!', '#NAME?', '#NULL!', '#NUM!', '#N/A']\n        error_details = {err: [] for err in excel_errors}\n        total_errors = 0\n        \n        for sheet_name in wb.sheetnames:\n            ws = wb[sheet_name]\n            # Check ALL rows and columns - no limits\n            for row in ws.iter_rows():\n                for cell in row:\n                    if cell.value is not None and isinstance(cell.value, str):\n                        for err in excel_errors:\n                            if err in cell.value:\n                                location = f\"{sheet_name}!{cell.coordinate}\"\n                                error_details[err].append(location)\n                                total_errors += 1\n                                break\n        \n        wb.close()\n        \n        # Build result summary\n        result = {\n            'status': 'success' if total_errors == 0 else 'errors_found',\n            'total_errors': total_errors,\n            'error_summary': {}\n        }\n        \n        # Add non-empty error categories\n        for err_type, locations in error_details.items():\n            if locations:\n                result['error_summary'][err_type] = {\n                    'count': len(locations),\n                    'locations': locations[:20]  # Show up to 20 locations\n                }\n        \n        # Add formula count for context - also check ALL cells\n        wb_formulas = load_workbook(filename, data_only=False)\n        formula_count = 0\n        for sheet_name in wb_formulas.sheetnames:\n            ws = wb_formulas[sheet_name]\n            for row in ws.iter_rows():\n                for cell in row:\n                    if cell.value and isinstance(cell.value, str) and cell.value.startswith('='):\n                        formula_count += 1\n        wb_formulas.close()\n        \n        result['total_formulas'] = formula_count\n        \n        return result\n        \n    except Exception as e:\n        return {'error': str(e)}\n\n\ndef main():\n    if len(sys.argv) < 2:\n        print(\"Usage: python recalc.py <excel_file> [timeout_seconds]\")\n        print(\"\\nRecalculates all formulas in an Excel file using LibreOffice\")\n        print(\"\\nReturns JSON with error details:\")\n        print(\"  - status: 'success' or 'errors_found'\")\n        print(\"  - total_errors: Total number of Excel errors found\")\n        print(\"  - total_formulas: Number of formulas in the file\")\n        print(\"  - error_summary: Breakdown by error type with locations\")\n        print(\"    - #VALUE!, #DIV/0!, #REF!, #NAME?, #NULL!, #NUM!, #N/A\")\n        sys.exit(1)\n    \n    filename = sys.argv[1]\n    timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 30\n    \n    result = recalc(filename, timeout)\n    print(json.dumps(result, indent=2))\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "domain-name-brainstormer/SKILL.md",
    "content": "---\nname: domain-name-brainstormer\ndescription: Generates creative domain name ideas for your project and checks availability across multiple TLDs (.com, .io, .dev, .ai, etc.). Saves hours of brainstorming and manual checking.\n---\n\n# Domain Name Brainstormer\n\nThis skill helps you find the perfect domain name for your project by generating creative options and checking what's actually available to register.\n\n## When to Use This Skill\n\n- Starting a new project or company\n- Launching a product or service\n- Creating a personal brand or portfolio site\n- Rebranding an existing project\n- Registering a domain for a side project\n- Finding available alternatives when your first choice is taken\n\n## What This Skill Does\n\n1. **Understands Your Project**: Analyzes what you're building and who it's for\n2. **Generates Creative Names**: Creates relevant, memorable domain options\n3. **Checks Availability**: Verifies which domains are actually available across multiple TLDs\n4. **Multiple Extensions**: Suggests .com, .io, .dev, .ai, .app, and more\n5. **Provides Alternatives**: Offers variations if top choices are taken\n6. **Branding Insights**: Explains why certain names work well\n\n## How to Use\n\n### Basic Brainstorming\n\n```\nI'm building a project management tool for remote teams. \nSuggest domain names.\n```\n\n```\nHelp me brainstorm domain names for a personal finance app\n```\n\n### Specific Preferences\n\n```\nI need a domain name for my AI writing assistant. \nPrefer short names with .ai or .io extension.\n```\n\n### With Keywords\n\n```\nSuggest domain names using the words \"pixel\" or \"studio\" \nfor my design agency\n```\n\n## Example\n\n**User**: \"I'm building a tool for developers to share code snippets. Suggest creative domain names.\"\n\n**Output**:\n```\nAnalyzing your project...\nTarget audience: Developers\nKey features: Code sharing, snippets, collaboration\n\n🎯 Domain Name Suggestions\n\n## Available (.com)\n1. ✓ snippetbox.com - Clear, memorable, available!\n   Why: Directly describes the product, easy to remember\n\n2. ✓ codeclip.com - Short and snappy\n   Why: Implies quick code sharing, only 8 characters\n\n3. ✓ devpaste.com - Developer-focused\n   Why: Familiar to devs (like pastebin), clear purpose\n\n## Available (Alternative TLDs)\n4. ✓ snippet.dev - Perfect extension for developers\n   Why: .dev extension signals developer tool\n\n5. ✓ codebox.io - Tech-forward\n   Why: .io popular with tech startups, clean name\n\n6. ✓ sharecode.app - Descriptive\n   Why: .app extension, clearly states the action\n\n## Premium/Taken (.com)\n- codeshare.com (Taken, est. $2,500)\n- snippets.com (Taken, premium domain)\n\n## Recommendations\n\n🏆 Top Pick: snippet.dev\n- Perfect for developer audience\n- Short and memorable  \n- .dev extension adds credibility\n- Available now!\n\n🥈 Runner-up: snippetbox.com\n- .com is universally recognized\n- Slightly longer but descriptive\n- Great brandability\n\nNext steps:\n1. Register your favorite before someone else does!\n2. Want me to check more variations?\n3. Need help with logo ideas for these names?\n```\n\n**Inspired by:** Ben Aiad's use case from Lenny's Newsletter\n\n## Domain Naming Tips\n\n### What Makes a Good Domain\n\n✓ **Short**: Under 15 characters ideal\n✓ **Memorable**: Easy to recall and spell\n✓ **Pronounceable**: Can be said in conversation\n✓ **Descriptive**: Hints at what you do\n✓ **Brandable**: Unique enough to stand out\n✓ **No hyphens**: Easier to share verbally\n\n### TLD Guide\n\n- **.com**: Universal, trusted, great for businesses\n- **.io**: Tech startups, developer tools\n- **.dev**: Developer-focused products\n- **.ai**: AI/ML products\n- **.app**: Mobile or web applications\n- **.co**: Alternative to .com\n- **.xyz**: Modern, creative projects\n- **.design**: Creative/design agencies\n- **.tech**: Technology companies\n\n## Advanced Features\n\n### Check Similar Variations\n\n```\nCheck availability for \"codebase\" and similar variations \nacross .com, .io, .dev\n```\n\n### Industry-Specific\n\n```\nSuggest domain names for a sustainable fashion brand, \nchecking .eco and .fashion TLDs\n```\n\n### Multilingual Options\n\n```\nBrainstorm domain names in English and Spanish for \na language learning app\n```\n\n### Competitor Analysis\n\n```\nShow me domain patterns used by successful project \nmanagement tools, then suggest similar available ones\n```\n\n## Example Workflows\n\n### Startup Launch\n1. Describe your startup idea\n2. Get 10-15 domain suggestions across TLDs\n3. Review availability and pricing\n4. Pick top 3 favorites\n5. Register immediately\n\n### Personal Brand\n1. Share your name and profession\n2. Get variations (firstname.com, firstnamelastname.dev, etc.)\n3. Check social media handle availability too\n4. Register consistent brand across platforms\n\n### Product Naming\n1. Describe product and target market\n2. Get creative, brandable names\n3. Check trademark conflicts\n4. Verify domain and social availability\n5. Test names with target audience\n\n## Tips for Success\n\n1. **Act Fast**: Good domains get taken quickly\n2. **Register Variations**: Get .com and .io to protect brand\n3. **Avoid Numbers**: Hard to communicate verbally\n4. **Check Social Media**: Make sure @username is available too\n5. **Say It Out Loud**: Test if it's easy to pronounce\n6. **Check Trademarks**: Ensure no legal conflicts\n7. **Think Long-term**: Will it still make sense in 5 years?\n\n## Pricing Context\n\nWhen suggesting domains, I'll note:\n- Standard domains: ~$10-15/year\n- Premium TLDs (.io, .ai): ~$30-50/year\n- Taken domains: Market price if listed\n- Premium domains: $hundreds to $thousands\n\n## Related Tools\n\nAfter picking a domain:\n- Check logo design options\n- Verify social media handles\n- Research trademark availability\n- Plan brand identity colors/fonts\n\n"
  },
  {
    "path": "file-organizer/SKILL.md",
    "content": "---\nname: file-organizer\ndescription: Intelligently organizes your files and folders across your computer by understanding context, finding duplicates, suggesting better structures, and automating cleanup tasks. Reduces cognitive load and keeps your digital workspace tidy without manual effort.\n---\n\n# File Organizer\n\nThis skill acts as your personal organization assistant, helping you maintain a clean, logical file structure across your computer without the mental overhead of constant manual organization.\n\n## When to Use This Skill\n\n- Your Downloads folder is a chaotic mess\n- You can't find files because they're scattered everywhere\n- You have duplicate files taking up space\n- Your folder structure doesn't make sense anymore\n- You want to establish better organization habits\n- You're starting a new project and need a good structure\n- You're cleaning up before archiving old projects\n\n## What This Skill Does\n\n1. **Analyzes Current Structure**: Reviews your folders and files to understand what you have\n2. **Finds Duplicates**: Identifies duplicate files across your system\n3. **Suggests Organization**: Proposes logical folder structures based on your content\n4. **Automates Cleanup**: Moves, renames, and organizes files with your approval\n5. **Maintains Context**: Makes smart decisions based on file types, dates, and content\n6. **Reduces Clutter**: Identifies old files you probably don't need anymore\n\n## How to Use\n\n### From Your Home Directory\n\n```\ncd ~\n```\n\nThen run Claude Code and ask for help:\n\n```\nHelp me organize my Downloads folder\n```\n\n```\nFind duplicate files in my Documents folder\n```\n\n```\nReview my project directories and suggest improvements\n```\n\n### Specific Organization Tasks\n\n```\nOrganize these downloads into proper folders based on what they are\n```\n\n```\nFind duplicate files and help me decide which to keep\n```\n\n```\nClean up old files I haven't touched in 6+ months\n```\n\n```\nCreate a better folder structure for my [work/projects/photos/etc]\n```\n\n## Instructions\n\nWhen a user requests file organization help:\n\n1. **Understand the Scope**\n   \n   Ask clarifying questions:\n   - Which directory needs organization? (Downloads, Documents, entire home folder?)\n   - What's the main problem? (Can't find things, duplicates, too messy, no structure?)\n   - Any files or folders to avoid? (Current projects, sensitive data?)\n   - How aggressively to organize? (Conservative vs. comprehensive cleanup)\n\n2. **Analyze Current State**\n   \n   Review the target directory:\n   ```bash\n   # Get overview of current structure\n   ls -la [target_directory]\n   \n   # Check file types and sizes\n   find [target_directory] -type f -exec file {} \\; | head -20\n   \n   # Identify largest files\n   du -sh [target_directory]/* | sort -rh | head -20\n   \n   # Count file types\n   find [target_directory] -type f | sed 's/.*\\.//' | sort | uniq -c | sort -rn\n   ```\n   \n   Summarize findings:\n   - Total files and folders\n   - File type breakdown\n   - Size distribution\n   - Date ranges\n   - Obvious organization issues\n\n3. **Identify Organization Patterns**\n   \n   Based on the files, determine logical groupings:\n   \n   **By Type**:\n   - Documents (PDFs, DOCX, TXT)\n   - Images (JPG, PNG, SVG)\n   - Videos (MP4, MOV)\n   - Archives (ZIP, TAR, DMG)\n   - Code/Projects (directories with code)\n   - Spreadsheets (XLSX, CSV)\n   - Presentations (PPTX, KEY)\n   \n   **By Purpose**:\n   - Work vs. Personal\n   - Active vs. Archive\n   - Project-specific\n   - Reference materials\n   - Temporary/scratch files\n   \n   **By Date**:\n   - Current year/month\n   - Previous years\n   - Very old (archive candidates)\n\n4. **Find Duplicates**\n   \n   When requested, search for duplicates:\n   ```bash\n   # Find exact duplicates by hash\n   find [directory] -type f -exec md5 {} \\; | sort | uniq -d\n   \n   # Find files with same name\n   find [directory] -type f -printf '%f\\n' | sort | uniq -d\n   \n   # Find similar-sized files\n   find [directory] -type f -printf '%s %p\\n' | sort -n\n   ```\n   \n   For each set of duplicates:\n   - Show all file paths\n   - Display sizes and modification dates\n   - Recommend which to keep (usually newest or best-named)\n   - **Important**: Always ask for confirmation before deleting\n\n5. **Propose Organization Plan**\n   \n   Present a clear plan before making changes:\n   \n   ```markdown\n   # Organization Plan for [Directory]\n   \n   ## Current State\n   - X files across Y folders\n   - [Size] total\n   - File types: [breakdown]\n   - Issues: [list problems]\n   \n   ## Proposed Structure\n   \n   ```\n   [Directory]/\n   ├── Work/\n   │   ├── Projects/\n   │   ├── Documents/\n   │   └── Archive/\n   ├── Personal/\n   │   ├── Photos/\n   │   ├── Documents/\n   │   └── Media/\n   └── Downloads/\n       ├── To-Sort/\n       └── Archive/\n   ```\n   \n   ## Changes I'll Make\n   \n   1. **Create new folders**: [list]\n   2. **Move files**:\n      - X PDFs → Work/Documents/\n      - Y images → Personal/Photos/\n      - Z old files → Archive/\n   3. **Rename files**: [any renaming patterns]\n   4. **Delete**: [duplicates or trash files]\n   \n   ## Files Needing Your Decision\n   \n   - [List any files you're unsure about]\n   \n   Ready to proceed? (yes/no/modify)\n   ```\n\n6. **Execute Organization**\n   \n   After approval, organize systematically:\n   \n   ```bash\n   # Create folder structure\n   mkdir -p \"path/to/new/folders\"\n   \n   # Move files with clear logging\n   mv \"old/path/file.pdf\" \"new/path/file.pdf\"\n   \n   # Rename files with consistent patterns\n   # Example: \"YYYY-MM-DD - Description.ext\"\n   ```\n   \n   **Important Rules**:\n   - Always confirm before deleting anything\n   - Log all moves for potential undo\n   - Preserve original modification dates\n   - Handle filename conflicts gracefully\n   - Stop and ask if you encounter unexpected situations\n\n7. **Provide Summary and Maintenance Tips**\n   \n   After organizing:\n   \n   ```markdown\n   # Organization Complete! ✨\n   \n   ## What Changed\n   \n   - Created [X] new folders\n   - Organized [Y] files\n   - Freed [Z] GB by removing duplicates\n   - Archived [W] old files\n   \n   ## New Structure\n   \n   [Show the new folder tree]\n   \n   ## Maintenance Tips\n   \n   To keep this organized:\n   \n   1. **Weekly**: Sort new downloads\n   2. **Monthly**: Review and archive completed projects\n   3. **Quarterly**: Check for new duplicates\n   4. **Yearly**: Archive old files\n   \n   ## Quick Commands for You\n   \n   ```bash\n   # Find files modified this week\n   find . -type f -mtime -7\n   \n   # Sort downloads by type\n   [custom command for their setup]\n   \n   # Find duplicates\n   [custom command]\n   ```\n   \n   Want to organize another folder?\n   ```\n\n## Examples\n\n### Example 1: Organizing Downloads (From Justin Dielmann)\n\n**User**: \"My Downloads folder is a mess with 500+ files. Help me organize it.\"\n\n**Process**:\n1. Analyzes Downloads folder\n2. Finds patterns: work docs, personal photos, installers, random PDFs\n3. Proposes structure:\n   - Downloads/\n     - Work/\n     - Personal/\n     - Installers/ (DMG, PKG files)\n     - Archive/\n     - ToSort/ (things needing decisions)\n4. Asks for confirmation\n5. Moves files intelligently based on content and names\n6. Results: 500 files → 5 organized folders\n\n### Example 2: Finding and Removing Duplicates\n\n**User**: \"Find duplicate files in my Documents and help me decide which to keep.\"\n\n**Output**:\n```markdown\n# Found 23 Sets of Duplicates (156 MB total)\n\n## Duplicate Set 1: \"proposal.pdf\"\n- `/Documents/proposal.pdf` (2.3 MB, modified: 2024-03-15)\n- `/Documents/old/proposal.pdf` (2.3 MB, modified: 2024-03-15)\n- `/Desktop/proposal.pdf` (2.3 MB, modified: 2024-03-10)\n\n**Recommendation**: Keep `/Documents/proposal.pdf` (most recent in correct location)\nDelete the other 2 copies?\n\n[Continue for all duplicates...]\n```\n\n### Example 3: Restructuring Projects Folder\n\n**User**: \"Review my ~/Projects directory and suggest improvements.\"\n\n**Output**:\n```markdown\n# Analysis of ~/Projects\n\n## Current Structure Issues\n- Mix of active and archived projects (3+ years old)\n- No consistent naming convention\n- Some projects at root, others in random subfolders\n- Duplicate folders (project-name, project-name-old, project-name-v2)\n\n## Proposed Structure\n\n```\nProjects/\n├── Active/\n│   ├── client-work/\n│   ├── side-projects/\n│   └── learning/\n├── Archive/\n│   ├── 2022/\n│   ├── 2023/\n│   └── 2024/\n└── Templates/\n```\n\n## Specific Changes\n1. Move 12 projects not touched since 2022 → Archive/\n2. Consolidate 4 duplicate project folders\n3. Rename projects to consistent format: \"client-name-project-name\"\n4. Create Archive for old work\n\nWant me to implement this?\n```\n\n### Example 4: Organizing Photos by Date\n\n**User**: \"Organize my photo folders by year and month.\"\n\n**Output**: Creates structure like:\n```\nPhotos/\n├── 2023/\n│   ├── 01-January/\n│   ├── 02-February/\n│   └── ...\n├── 2024/\n│   ├── 01-January/\n│   └── ...\n└── Unsorted/\n```\n\nThen moves photos based on EXIF data or file modification dates.\n\n## Common Organization Tasks\n\n### Downloads Cleanup\n```\nOrganize my Downloads folder - move documents to Documents, \nimages to Pictures, keep installers separate, and archive files \nolder than 3 months.\n```\n\n### Project Organization\n```\nReview my Projects folder structure and help me separate active \nprojects from old ones I should archive.\n```\n\n### Duplicate Removal\n```\nFind all duplicate files in my Documents folder and help me \ndecide which ones to keep.\n```\n\n### Desktop Cleanup\n```\nMy Desktop is covered in files. Help me organize everything into \nmy Documents folder properly.\n```\n\n### Photo Organization\n```\nOrganize all photos in this folder by date (year/month) based \non when they were taken.\n```\n\n### Work/Personal Separation\n```\nHelp me separate my work files from personal files across my \nDocuments folder.\n```\n\n## Pro Tips\n\n1. **Start Small**: Begin with one messy folder (like Downloads) to build trust\n2. **Regular Maintenance**: Run weekly cleanup on Downloads\n3. **Consistent Naming**: Use \"YYYY-MM-DD - Description\" format for important files\n4. **Archive Aggressively**: Move old projects to Archive instead of deleting\n5. **Keep Active Separate**: Maintain clear boundaries between active and archived work\n6. **Trust the Process**: Let Claude handle the cognitive load of where things go\n\n## Best Practices\n\n### Folder Naming\n- Use clear, descriptive names\n- Avoid spaces (use hyphens or underscores)\n- Be specific: \"client-proposals\" not \"docs\"\n- Use prefixes for ordering: \"01-current\", \"02-archive\"\n\n### File Naming\n- Include dates: \"2024-10-17-meeting-notes.md\"\n- Be descriptive: \"q3-financial-report.xlsx\"\n- Avoid version numbers in names (use version control instead)\n- Remove download artifacts: \"document-final-v2 (1).pdf\" → \"document.pdf\"\n\n### When to Archive\n- Projects not touched in 6+ months\n- Completed work that might be referenced later\n- Old versions after migration to new systems\n- Files you're hesitant to delete (archive first)\n\n## Related Use Cases\n\n- Setting up organization for a new computer\n- Preparing files for backup/archiving\n- Cleaning up before storage cleanup\n- Organizing shared team folders\n- Structuring new project directories\n\n"
  },
  {
    "path": "image-enhancer/SKILL.md",
    "content": "---\nname: image-enhancer\ndescription: Improves the quality of images, especially screenshots, by enhancing resolution, sharpness, and clarity. Perfect for preparing images for presentations, documentation, or social media posts.\n---\n\n# Image Enhancer\n\nThis skill takes your images and screenshots and makes them look better—sharper, clearer, and more professional.\n\n## When to Use This Skill\n\n- Improving screenshot quality for blog posts or documentation\n- Enhancing images before sharing on social media\n- Preparing images for presentations or reports\n- Upscaling low-resolution images\n- Sharpening blurry photos\n- Cleaning up compressed images\n\n## What This Skill Does\n\n1. **Analyzes Image Quality**: Checks resolution, sharpness, and compression artifacts\n2. **Enhances Resolution**: Upscales images intelligently\n3. **Improves Sharpness**: Enhances edges and details\n4. **Reduces Artifacts**: Cleans up compression artifacts and noise\n5. **Optimizes for Use Case**: Adjusts based on intended use (web, print, social media)\n\n## How to Use\n\n### Basic Enhancement\n\n```\nImprove the image quality of screenshot.png\n```\n\n```\nEnhance all images in this folder\n```\n\n### Specific Improvements\n\n```\nUpscale this image to 4K resolution\n```\n\n```\nSharpen this blurry screenshot\n```\n\n```\nReduce compression artifacts in this image\n```\n\n### Batch Processing\n\n```\nImprove the quality of all PNG files in this directory\n```\n\n## Example\n\n**User**: \"Improve the image quality of screenshot-2024.png\"\n\n**Output**:\n```\nAnalyzing screenshot-2024.png...\n\nCurrent specs:\n- Resolution: 1920x1080\n- Format: PNG\n- Quality: Good, but slight blur\n\nEnhancements applied:\n✓ Upscaled to 2560x1440 (retina)\n✓ Sharpened edges\n✓ Enhanced text clarity\n✓ Optimized file size\n\nSaved as: screenshot-2024-enhanced.png\nOriginal preserved as: screenshot-2024-original.png\n```\n\n**Inspired by:** Lenny Rachitsky's workflow from his newsletter - used for screenshots in his articles\n\n## Tips\n\n- Always keeps original files as backup\n- Works best with screenshots and digital images\n- Can batch process entire folders\n- Specify output format if needed (PNG for quality, JPG for smaller size)\n- For social media, mention the platform for optimal sizing\n\n## Common Use Cases\n\n- **Blog Posts**: Enhance screenshots before publishing\n- **Documentation**: Make UI screenshots crystal clear\n- **Social Media**: Optimize images for Twitter, LinkedIn, Instagram\n- **Presentations**: Upscale images for large screens\n- **Print Materials**: Increase resolution for physical media\n\n"
  },
  {
    "path": "internal-comms/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "internal-comms/SKILL.md",
    "content": "---\nname: internal-comms\ndescription: A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).\nlicense: Complete terms in LICENSE.txt\n---\n\n## When to use this skill\nTo write internal communications, use this skill for:\n- 3P updates (Progress, Plans, Problems)\n- Company newsletters\n- FAQ responses\n- Status reports\n- Leadership updates\n- Project updates\n- Incident reports\n\n## How to use this skill\n\nTo write any internal communication:\n\n1. **Identify the communication type** from the request\n2. **Load the appropriate guideline file** from the `examples/` directory:\n    - `examples/3p-updates.md` - For Progress/Plans/Problems team updates\n    - `examples/company-newsletter.md` - For company-wide newsletters\n    - `examples/faq-answers.md` - For answering frequently asked questions\n    - `examples/general-comms.md` - For anything else that doesn't explicitly match one of the above\n3. **Follow the specific instructions** in that file for formatting, tone, and content gathering\n\nIf the communication type doesn't match any existing guideline, ask for clarification or more context about the desired format.\n\n## Keywords\n3P updates, company newsletter, company comms, weekly update, faqs, common questions, updates, internal comms\n"
  },
  {
    "path": "internal-comms/examples/3p-updates.md",
    "content": "## Instructions\nYou are being asked to write a 3P update. 3P updates stand for \"Progress, Plans, Problems.\" The main audience is for executives, leadership, other teammates, etc. They're meant to be very succinct and to-the-point: think something you can read in 30-60sec or less. They're also for people with some, but not a lot of context on what the team does.\n\n3Ps can cover a team of any size, ranging all the way up to the entire company. The bigger the team, the less granular the tasks should be. For example, \"mobile team\" might have \"shipped feature\" or \"fixed bugs,\" whereas the company might have really meaty 3Ps, like \"hired 20 new people\" or \"closed 10 new deals.\" \n\nThey represent the work of the team across a time period, almost always one week. They include three sections:\n1) Progress: what the team has accomplished over the next time period. Focus mainly on things shipped, milestones achieved, tasks created, etc.\n2) Plans: what the team plans to do over the next time period. Focus on what things are top-of-mind, really high priority, etc. for the team.\n3) Problems: anything that is slowing the team down. This could be things like too few people, bugs or blockers that are preventing the team from moving forward, some deal that fell through, etc.\n\nBefore writing them, make sure that you know the team name. If it's not specified, you can ask explicitly what the team name you're writing for is.\n\n\n## Tools Available\nWhenever possible, try to pull from available sources to get the information you need:\n- Slack: posts from team members with their updates - ideally look for posts in large channels with lots of reactions\n- Google Drive: docs written from critical team members with lots of views\n- Email: emails with lots of responses of lots of content that seems relevant\n- Calendar: non-recurring meetings that have a lot of importance, like product reviews, etc.\n\n\nTry to gather as much context as you can, focusing on the things that covered the time period you're writing for:\n- Progress: anything between a week ago and today\n- Plans: anything from today to the next week\n- Problems: anything between a week ago and today\n\n\nIf you don't have access, you can ask the user for things they want to cover. They might also include these things to you directly, in which case you're mostly just formatting for this particular format.\n\n## Workflow\n\n1. **Clarify scope**: Confirm the team name and time period (usually past week for Progress/Problems, next\nweek for Plans)\n2. **Gather information**: Use available tools or ask the user directly\n3. **Draft the update**: Follow the strict formatting guidelines\n4. **Review**: Ensure it's concise (30-60 seconds to read) and data-driven\n\n## Formatting\n\nThe format is always the same, very strict formatting. Never use any formatting other than this. Pick an emoji that is fun and captures the vibe of the team and update.\n\n[pick an emoji] [Team Name] (Dates Covered, usually a week)\nProgress: [1-3 sentences of content]\nPlans: [1-3 sentences of content]\nProblems: [1-3 sentences of content]\n\nEach section should be no more than 1-3 sentences: clear, to the point. It should be data-driven, and generally include metrics where possible. The tone should be very matter-of-fact, not super prose-heavy."
  },
  {
    "path": "internal-comms/examples/company-newsletter.md",
    "content": "## Instructions\nYou are being asked to write a company-wide newsletter update. You are meant to summarize the past week/month of a company in the form of a newsletter that the entire company will read. It should be maybe ~20-25 bullet points long. It will be sent via Slack and email, so make it consumable for that.\n\nIdeally it includes the following attributes:\n- Lots of links: pulling documents from Google Drive that are very relevant, linking to prominent Slack messages in announce channels and from executives, perhgaps referencing emails that went company-wide, highlighting significant things that have happened in the company.\n- Short and to-the-point: each bullet should probably be no longer than ~1-2 sentences\n- Use the \"we\" tense, as you are part of the company. Many of the bullets should say \"we did this\" or \"we did that\"\n\n## Tools to use\nIf you have access to the following tools, please try to use them. If not, you can also let the user know directly that their responses would be better if they gave them access.\n\n- Slack: look for messages in channels with lots of people, with lots of reactions or lots of responses within the thread\n- Email: look for things from executives that discuss company-wide announcements\n- Calendar: if there were meetings with large attendee lists, particularly things like All-Hands meetings, big company announcements, etc. If there were documents attached to those meetings, those are great links to include.\n- Documents: if there were new docs published in the last week or two that got a lot of attention, you can link them. These should be things like company-wide vision docs, plans for the upcoming quarter or half, things authored by critical executives, etc.\n- External press: if you see references to articles or press we've received over the past week, that could be really cool too.\n\nIf you don't have access to any of these things, you can ask the user for things they want to cover. In this case, you'll mostly just be polishing up and fitting to this format more directly.\n\n## Sections\nThe company is pretty big: 1000+ people. There are a variety of different teams and initiatives going on across the company. To make sure the update works well, try breaking it into sections of similar things. You might break into clusters like {product development, go to market, finance} or {recruiting, execution, vision}, or {external news, internal news} etc. Try to make sure the different areas of the company are highlighted well.\n\n## Prioritization\nFocus on:\n- Company-wide impact (not team-specific details)\n- Announcements from leadership\n- Major milestones and achievements\n- Information that affects most employees\n- External recognition or press\n\nAvoid:\n- Overly granular team updates (save those for 3Ps)\n- Information only relevant to small groups\n- Duplicate information already communicated\n\n## Example Formats\n\n:megaphone: Company Announcements\n- Announcement 1\n- Announcement 2\n- Announcement 3\n\n:dart: Progress on Priorities\n- Area 1\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n- Area 2\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n- Area 3\n    - Sub-area 1\n    - Sub-area 2\n    - Sub-area 3\n\n:pillar: Leadership Updates\n- Post 1\n- Post 2\n- Post 3\n\n:thread: Social Updates\n- Update 1\n- Update 2\n- Update 3\n"
  },
  {
    "path": "internal-comms/examples/faq-answers.md",
    "content": "## Instructions\nYou are an assistant for answering questions that are being asked across the company. Every week, there are lots of questions that get asked across the company, and your goal is to try to summarize what those questions are. We want our company to be well-informed and on the same page, so your job is to produce a set of frequently asked questions that our employees are asking and attempt to answer them. Your singular job is to do two things:\n\n- Find questions that are big sources of confusion for lots of employees at the company, generally about things that affect a large portion of the employee base\n- Attempt to give a nice summarized answer to that question in order to minimize confusion.\n\nSome examples of areas that may be interesting to folks: recent corporate events (fundraising, new executives, etc.), upcoming launches, hiring progress, changes to vision or focus, etc.\n\n\n## Tools Available\nYou should use the company's available tools, where communication and work happens. For most companies, it looks something like this:\n- Slack: questions being asked across the company - it could be questions in response to posts with lots of responses, questions being asked with lots of reactions or thumbs up to show support, or anything else to show that a large number of employees want to ask the same things\n- Email: emails with FAQs written directly in them can be a good source as well\n- Documents: docs in places like Google Drive, linked on calendar events, etc. can also be a good source of FAQs, either directly added or inferred based on the contents of the doc\n\n## Formatting\nThe formatting should be pretty basic:\n\n- *Question*: [insert question - 1 sentence]\n- *Answer*: [insert answer - 1-2 sentence]\n\n## Guidance\nMake sure you're being holistic in your questions. Don't focus too much on just the user in question or the team they are a part of, but try to capture the entire company. Try to be as holistic as you can in reading all the tools available, producing responses that are relevant to all at the company.\n\n## Answer Guidelines\n- Base answers on official company communications when possible\n- If information is uncertain, indicate that clearly\n- Link to authoritative sources (docs, announcements, emails)\n- Keep tone professional but approachable\n- Flag if a question requires executive input or official response"
  },
  {
    "path": "internal-comms/examples/general-comms.md",
    "content": "  ## Instructions\n  You are being asked to write internal company communication that doesn't fit into the standard formats (3P\n  updates, newsletters, or FAQs).\n\n  Before proceeding:\n  1. Ask the user about their target audience\n  2. Understand the communication's purpose\n  3. Clarify the desired tone (formal, casual, urgent, informational)\n  4. Confirm any specific formatting requirements\n\n  Use these general principles:\n  - Be clear and concise\n  - Use active voice\n  - Put the most important information first\n  - Include relevant links and references\n  - Match the company's communication style"
  },
  {
    "path": "invoice-organizer/SKILL.md",
    "content": "---\nname: invoice-organizer\ndescription: Automatically organizes invoices and receipts for tax preparation by reading messy files, extracting key information, renaming them consistently, and sorting them into logical folders. Turns hours of manual bookkeeping into minutes of automated organization.\n---\n\n# Invoice Organizer\n\nThis skill transforms chaotic folders of invoices, receipts, and financial documents into a clean, tax-ready filing system without manual effort.\n\n## When to Use This Skill\n\n- Preparing for tax season and need organized records\n- Managing business expenses across multiple vendors\n- Organizing receipts from a messy folder or email downloads\n- Setting up automated invoice filing for ongoing bookkeeping\n- Archiving financial records by year or category\n- Reconciling expenses for reimbursement\n- Preparing documentation for accountants\n\n## What This Skill Does\n\n1. **Reads Invoice Content**: Extracts information from PDFs, images, and documents:\n   - Vendor/company name\n   - Invoice number\n   - Date\n   - Amount\n   - Product or service description\n   - Payment method\n\n2. **Renames Files Consistently**: Creates standardized filenames:\n   - Format: `YYYY-MM-DD Vendor - Invoice - ProductOrService.pdf`\n   - Examples: `2024-03-15 Adobe - Invoice - Creative Cloud.pdf`\n\n3. **Organizes by Category**: Sorts into logical folders:\n   - By vendor\n   - By expense category (software, office, travel, etc.)\n   - By time period (year, quarter, month)\n   - By tax category (deductible, personal, etc.)\n\n4. **Handles Multiple Formats**: Works with:\n   - PDF invoices\n   - Scanned receipts (JPG, PNG)\n   - Email attachments\n   - Screenshots\n   - Bank statements\n\n5. **Maintains Originals**: Preserves original files while organizing copies\n\n## How to Use\n\n### Basic Usage\n\nNavigate to your messy invoice folder:\n```\ncd ~/Desktop/receipts-to-sort\n```\n\nThen ask Claude Code:\n```\nOrganize these invoices for taxes\n```\n\nOr more specifically:\n```\nRead all invoices in this folder, rename them to \n\"YYYY-MM-DD Vendor - Invoice - Product.pdf\" format, \nand organize them by vendor\n```\n\n### Advanced Organization\n\n```\nOrganize these invoices:\n1. Extract date, vendor, and description from each file\n2. Rename to standard format\n3. Sort into folders by expense category (Software, Office, Travel, etc.)\n4. Create a CSV spreadsheet with all invoice details for my accountant\n```\n\n## Instructions\n\nWhen a user requests invoice organization:\n\n1. **Scan the Folder**\n   \n   Identify all invoice files:\n   ```bash\n   # Find all invoice-related files\n   find . -type f \\( -name \"*.pdf\" -o -name \"*.jpg\" -o -name \"*.png\" \\) -print\n   ```\n   \n   Report findings:\n   - Total number of files\n   - File types\n   - Date range (if discernible from names)\n   - Current organization (or lack thereof)\n\n2. **Extract Information from Each File**\n   \n   For each invoice, extract:\n   \n   **From PDF invoices**:\n   - Use text extraction to read invoice content\n   - Look for common patterns:\n     - \"Invoice Date:\", \"Date:\", \"Issued:\"\n     - \"Invoice #:\", \"Invoice Number:\"\n     - Company name (usually at top)\n     - \"Amount Due:\", \"Total:\", \"Amount:\"\n     - \"Description:\", \"Service:\", \"Product:\"\n   \n   **From image receipts**:\n   - Read visible text from images\n   - Identify vendor name (often at top)\n   - Look for date (common formats)\n   - Find total amount\n   \n   **Fallback for unclear files**:\n   - Use filename clues\n   - Check file creation/modification date\n   - Flag for manual review if critical info missing\n\n3. **Determine Organization Strategy**\n   \n   Ask user preference if not specified:\n   \n   ```markdown\n   I found [X] invoices from [date range].\n   \n   How would you like them organized?\n   \n   1. **By Vendor** (Adobe/, Amazon/, Stripe/, etc.)\n   2. **By Category** (Software/, Office Supplies/, Travel/, etc.)\n   3. **By Date** (2024/Q1/, 2024/Q2/, etc.)\n   4. **By Tax Category** (Deductible/, Personal/, etc.)\n   5. **Custom** (describe your structure)\n   \n   Or I can use a default structure: Year/Category/Vendor\n   ```\n\n4. **Create Standardized Filename**\n   \n   For each invoice, create a filename following this pattern:\n   \n   ```\n   YYYY-MM-DD Vendor - Invoice - Description.ext\n   ```\n   \n   Examples:\n   - `2024-03-15 Adobe - Invoice - Creative Cloud.pdf`\n   - `2024-01-10 Amazon - Receipt - Office Supplies.pdf`\n   - `2023-12-01 Stripe - Invoice - Monthly Payment Processing.pdf`\n   \n   **Filename Best Practices**:\n   - Remove special characters except hyphens\n   - Capitalize vendor names properly\n   - Keep descriptions concise but meaningful\n   - Use consistent date format (YYYY-MM-DD) for sorting\n   - Preserve original file extension\n\n5. **Execute Organization**\n   \n   Before moving files, show the plan:\n   \n   ```markdown\n   # Organization Plan\n   \n   ## Proposed Structure\n   ```\n   Invoices/\n   ├── 2023/\n   │   ├── Software/\n   │   │   ├── Adobe/\n   │   │   └── Microsoft/\n   │   ├── Services/\n   │   └── Office/\n   └── 2024/\n       ├── Software/\n       ├── Services/\n       └── Office/\n   ```\n   \n   ## Sample Changes\n   \n   Before: `invoice_adobe_march.pdf`\n   After: `2024-03-15 Adobe - Invoice - Creative Cloud.pdf`\n   Location: `Invoices/2024/Software/Adobe/`\n   \n   Before: `IMG_2847.jpg`\n   After: `2024-02-10 Staples - Receipt - Office Supplies.jpg`\n   Location: `Invoices/2024/Office/Staples/`\n   \n   Process [X] files? (yes/no)\n   ```\n   \n   After approval:\n   ```bash\n   # Create folder structure\n   mkdir -p \"Invoices/2024/Software/Adobe\"\n   \n   # Copy (don't move) to preserve originals\n   cp \"original.pdf\" \"Invoices/2024/Software/Adobe/2024-03-15 Adobe - Invoice - Creative Cloud.pdf\"\n   \n   # Or move if user prefers\n   mv \"original.pdf\" \"new/path/standardized-name.pdf\"\n   ```\n\n6. **Generate Summary Report**\n   \n   Create a CSV file with all invoice details:\n   \n   ```csv\n   Date,Vendor,Invoice Number,Description,Amount,Category,File Path\n   2024-03-15,Adobe,INV-12345,Creative Cloud,52.99,Software,Invoices/2024/Software/Adobe/2024-03-15 Adobe - Invoice - Creative Cloud.pdf\n   2024-03-10,Amazon,123-4567890-1234567,Office Supplies,127.45,Office,Invoices/2024/Office/Amazon/2024-03-10 Amazon - Receipt - Office Supplies.pdf\n   ...\n   ```\n   \n   This CSV is useful for:\n   - Importing into accounting software\n   - Sharing with accountants\n   - Expense tracking and reporting\n   - Tax preparation\n\n7. **Provide Completion Summary**\n   \n   ```markdown\n   # Organization Complete! 📊\n   \n   ## Summary\n   - **Processed**: [X] invoices\n   - **Date range**: [earliest] to [latest]\n   - **Total amount**: $[sum] (if amounts extracted)\n   - **Vendors**: [Y] unique vendors\n   \n   ## New Structure\n   ```\n   Invoices/\n   ├── 2024/ (45 files)\n   │   ├── Software/ (23 files)\n   │   ├── Services/ (12 files)\n   │   └── Office/ (10 files)\n   └── 2023/ (12 files)\n   ```\n   \n   ## Files Created\n   - `/Invoices/` - Organized invoices\n   - `/Invoices/invoice-summary.csv` - Spreadsheet for accounting\n   - `/Invoices/originals/` - Original files (if copied)\n   \n   ## Files Needing Review\n   [List any files where information couldn't be extracted completely]\n   \n   ## Next Steps\n   1. Review the `invoice-summary.csv` file\n   2. Check files in \"Needs Review\" folder\n   3. Import CSV into your accounting software\n   4. Set up auto-organization for future invoices\n   \n   Ready for tax season! 🎉\n   ```\n\n## Examples\n\n### Example 1: Tax Preparation (From Martin Merschroth)\n\n**User**: \"I have a messy folder of invoices for taxes. Sort them and rename properly.\"\n\n**Process**:\n1. Scans folder: finds 147 PDFs and images\n2. Reads each invoice to extract:\n   - Date\n   - Vendor name\n   - Invoice number\n   - Product/service description\n3. Renames all files: `YYYY-MM-DD Vendor - Invoice - Product.pdf`\n4. Organizes into: `2024/Software/`, `2024/Travel/`, etc.\n5. Creates `invoice-summary.csv` for accountant\n6. Result: Tax-ready organized invoices in minutes\n\n### Example 2: Monthly Expense Reconciliation\n\n**User**: \"Organize my business receipts from last month by category.\"\n\n**Output**:\n```markdown\n# March 2024 Receipts Organized\n\n## By Category\n- Software & Tools: $847.32 (12 invoices)\n- Office Supplies: $234.18 (8 receipts)\n- Travel & Meals: $1,456.90 (15 receipts)\n- Professional Services: $2,500.00 (3 invoices)\n\nTotal: $5,038.40\n\nAll receipts renamed and filed in:\n`Business-Receipts/2024/03-March/[Category]/`\n\nCSV export: `march-2024-expenses.csv`\n```\n\n### Example 3: Multi-Year Archive\n\n**User**: \"I have 3 years of random invoices. Organize them by year, then by vendor.\"\n\n**Output**: Creates structure:\n```\nInvoices/\n├── 2022/\n│   ├── Adobe/\n│   ├── Amazon/\n│   └── ...\n├── 2023/\n│   ├── Adobe/\n│   ├── Amazon/\n│   └── ...\n└── 2024/\n    ├── Adobe/\n    ├── Amazon/\n    └── ...\n```\n\nEach file properly renamed with date and description.\n\n### Example 4: Email Downloads Cleanup\n\n**User**: \"I download invoices from Gmail. They're all named 'invoice.pdf', 'invoice(1).pdf', etc. Fix this mess.\"\n\n**Output**:\n```markdown\nFound 89 files all named \"invoice*.pdf\"\n\nReading each file to extract real information...\n\nRenamed examples:\n- invoice.pdf → 2024-03-15 Shopify - Invoice - Monthly Subscription.pdf\n- invoice(1).pdf → 2024-03-14 Google - Invoice - Workspace.pdf\n- invoice(2).pdf → 2024-03-10 Netlify - Invoice - Pro Plan.pdf\n\nAll files renamed and organized by vendor.\n```\n\n## Common Organization Patterns\n\n### By Vendor (Simple)\n```\nInvoices/\n├── Adobe/\n├── Amazon/\n├── Google/\n└── Microsoft/\n```\n\n### By Year and Category (Tax-Friendly)\n```\nInvoices/\n├── 2023/\n│   ├── Software/\n│   ├── Hardware/\n│   ├── Services/\n│   └── Travel/\n└── 2024/\n    └── ...\n```\n\n### By Quarter (Detailed Tracking)\n```\nInvoices/\n├── 2024/\n│   ├── Q1/\n│   │   ├── Software/\n│   │   ├── Office/\n│   │   └── Travel/\n│   └── Q2/\n│       └── ...\n```\n\n### By Tax Category (Accountant-Ready)\n```\nInvoices/\n├── Deductible/\n│   ├── Software/\n│   ├── Office/\n│   └── Professional-Services/\n├── Partially-Deductible/\n│   └── Meals-Travel/\n└── Personal/\n```\n\n## Automation Setup\n\nFor ongoing organization:\n\n```\nCreate a script that watches my ~/Downloads/invoices folder \nand auto-organizes any new invoice files using our standard \nnaming and folder structure.\n```\n\nThis creates a persistent solution that organizes invoices as they arrive.\n\n## Pro Tips\n\n1. **Scan emails to PDF**: Use Preview or similar to save email invoices as PDFs first\n2. **Consistent downloads**: Save all invoices to one folder for batch processing\n3. **Monthly routine**: Organize invoices monthly, not annually\n4. **Backup originals**: Keep original files before reorganizing\n5. **Include amounts in CSV**: Useful for budget tracking\n6. **Tag by deductibility**: Note which expenses are tax-deductible\n7. **Keep receipts 7 years**: Standard audit period\n\n## Handling Special Cases\n\n### Missing Information\nIf date/vendor can't be extracted:\n- Flag file for manual review\n- Use file modification date as fallback\n- Create \"Needs-Review/\" folder\n\n### Duplicate Invoices\nIf same invoice appears multiple times:\n- Compare file hashes\n- Keep highest quality version\n- Note duplicates in summary\n\n### Multi-Page Invoices\nFor invoices split across files:\n- Merge PDFs if needed\n- Use consistent naming for parts\n- Note in CSV if invoice is split\n\n### Non-Standard Formats\nFor unusual receipt formats:\n- Extract what's possible\n- Standardize what you can\n- Flag for review if critical info missing\n\n## Related Use Cases\n\n- Creating expense reports for reimbursement\n- Organizing bank statements\n- Managing vendor contracts\n- Archiving old financial records\n- Preparing for audits\n- Tracking subscription costs over time\n\n"
  },
  {
    "path": "langsmith-fetch/SKILL.md",
    "content": "---\nname: langsmith-fetch\ndescription: Debug LangChain and LangGraph agents by fetching execution traces from LangSmith Studio. Use when debugging agent behavior, investigating errors, analyzing tool calls, checking memory operations, or examining agent performance. Automatically fetches recent traces and analyzes execution patterns. Requires langsmith-fetch CLI installed.\n---\n\n# LangSmith Fetch - Agent Debugging Skill\n\nDebug LangChain and LangGraph agents by fetching execution traces directly from LangSmith Studio in your terminal.\n\n## When to Use This Skill\n\nAutomatically activate when user mentions:\n- 🐛 \"Debug my agent\" or \"What went wrong?\"\n- 🔍 \"Show me recent traces\" or \"What happened?\"\n- ❌ \"Check for errors\" or \"Why did it fail?\"\n- 💾 \"Analyze memory operations\" or \"Check LTM\"\n- 📊 \"Review agent performance\" or \"Check token usage\"\n- 🔧 \"What tools were called?\" or \"Show execution flow\"\n\n## Prerequisites\n\n### 1. Install langsmith-fetch\n```bash\npip install langsmith-fetch\n```\n\n### 2. Set Environment Variables\n```bash\nexport LANGSMITH_API_KEY=\"your_langsmith_api_key\"\nexport LANGSMITH_PROJECT=\"your_project_name\"\n```\n\n**Verify setup:**\n```bash\necho $LANGSMITH_API_KEY\necho $LANGSMITH_PROJECT\n```\n\n## Core Workflows\n\n### Workflow 1: Quick Debug Recent Activity\n\n**When user asks:** \"What just happened?\" or \"Debug my agent\"\n\n**Execute:**\n```bash\nlangsmith-fetch traces --last-n-minutes 5 --limit 5 --format pretty\n```\n\n**Analyze and report:**\n1. ✅ Number of traces found\n2. ⚠️ Any errors or failures\n3. 🛠️ Tools that were called\n4. ⏱️ Execution times\n5. 💰 Token usage\n\n**Example response format:**\n```\nFound 3 traces in the last 5 minutes:\n\nTrace 1: ✅ Success\n- Agent: memento\n- Tools: recall_memories, create_entities\n- Duration: 2.3s\n- Tokens: 1,245\n\nTrace 2: ❌ Error\n- Agent: cypher\n- Error: \"Neo4j connection timeout\"\n- Duration: 15.1s\n- Failed at: search_nodes tool\n\nTrace 3: ✅ Success\n- Agent: memento\n- Tools: store_memory\n- Duration: 1.8s\n- Tokens: 892\n\n💡 Issue found: Trace 2 failed due to Neo4j timeout. Recommend checking database connection.\n```\n\n---\n\n### Workflow 2: Deep Dive Specific Trace\n\n**When user provides:** Trace ID or says \"investigate that error\"\n\n**Execute:**\n```bash\nlangsmith-fetch trace <trace-id> --format json\n```\n\n**Analyze JSON and report:**\n1. 🎯 What the agent was trying to do\n2. 🛠️ Which tools were called (in order)\n3. ✅ Tool results (success/failure)\n4. ❌ Error messages (if any)\n5. 💡 Root cause analysis\n6. 🔧 Suggested fix\n\n**Example response format:**\n```\nDeep Dive Analysis - Trace abc123\n\nGoal: User asked \"Find all projects in Neo4j\"\n\nExecution Flow:\n1. ✅ search_nodes(query: \"projects\")\n   → Found 24 nodes\n\n2. ❌ get_node_details(node_id: \"proj_123\")\n   → Error: \"Node not found\"\n   → This is the failure point\n\n3. ⏹️ Execution stopped\n\nRoot Cause:\nThe search_nodes tool returned node IDs that no longer exist in the database,\npossibly due to recent deletions.\n\nSuggested Fix:\n1. Add error handling in get_node_details tool\n2. Filter deleted nodes in search results\n3. Update cache invalidation strategy\n\nToken Usage: 1,842 tokens ($0.0276)\nExecution Time: 8.7 seconds\n```\n\n---\n\n### Workflow 3: Export Debug Session\n\n**When user says:** \"Save this session\" or \"Export traces\"\n\n**Execute:**\n```bash\n# Create session folder with timestamp\nSESSION_DIR=\"langsmith-debug/session-$(date +%Y%m%d-%H%M%S)\"\nmkdir -p \"$SESSION_DIR\"\n\n# Export traces\nlangsmith-fetch traces \"$SESSION_DIR/traces\" --last-n-minutes 30 --limit 50 --include-metadata\n\n# Export threads (conversations)\nlangsmith-fetch threads \"$SESSION_DIR/threads\" --limit 20\n```\n\n**Report:**\n```\n✅ Session exported successfully!\n\nLocation: langsmith-debug/session-20251224-143022/\n- Traces: 42 files\n- Threads: 8 files\n\nYou can now:\n1. Review individual trace files\n2. Share folder with team\n3. Analyze with external tools\n4. Archive for future reference\n\nSession size: 2.3 MB\n```\n\n---\n\n### Workflow 4: Error Detection\n\n**When user asks:** \"Show me errors\" or \"What's failing?\"\n\n**Execute:**\n```bash\n# Fetch recent traces\nlangsmith-fetch traces --last-n-minutes 30 --limit 50 --format json > recent-traces.json\n\n# Search for errors\ngrep -i \"error\\|failed\\|exception\" recent-traces.json\n```\n\n**Analyze and report:**\n1. 📊 Total errors found\n2. ❌ Error types and frequency\n3. 🕐 When errors occurred\n4. 🎯 Which agents/tools failed\n5. 💡 Common patterns\n\n**Example response format:**\n```\nError Analysis - Last 30 Minutes\n\nTotal Traces: 50\nFailed Traces: 7 (14% failure rate)\n\nError Breakdown:\n1. Neo4j Connection Timeout (4 occurrences)\n   - Agent: cypher\n   - Tool: search_nodes\n   - First occurred: 14:32\n   - Last occurred: 14:45\n   - Pattern: Happens during peak load\n\n2. Memory Store Failed (2 occurrences)\n   - Agent: memento\n   - Tool: store_memory\n   - Error: \"Pinecone rate limit exceeded\"\n   - Occurred: 14:38, 14:41\n\n3. Tool Not Found (1 occurrence)\n   - Agent: sqlcrm\n   - Attempted tool: \"export_report\" (doesn't exist)\n   - Occurred: 14:35\n\n💡 Recommendations:\n1. Add retry logic for Neo4j timeouts\n2. Implement rate limiting for Pinecone\n3. Fix sqlcrm tool configuration\n```\n\n---\n\n## Common Use Cases\n\n### Use Case 1: \"Agent Not Responding\"\n\n**User says:** \"My agent isn't doing anything\"\n\n**Steps:**\n1. Check if traces exist:\n   ```bash\n   langsmith-fetch traces --last-n-minutes 5 --limit 5\n   ```\n\n2. **If NO traces found:**\n   - Tracing might be disabled\n   - Check: `LANGCHAIN_TRACING_V2=true` in environment\n   - Check: `LANGCHAIN_API_KEY` is set\n   - Verify agent actually ran\n\n3. **If traces found:**\n   - Review for errors\n   - Check execution time (hanging?)\n   - Verify tool calls completed\n\n---\n\n### Use Case 2: \"Wrong Tool Called\"\n\n**User says:** \"Why did it use the wrong tool?\"\n\n**Steps:**\n1. Get the specific trace\n2. Review available tools at execution time\n3. Check agent's reasoning for tool selection\n4. Examine tool descriptions/instructions\n5. Suggest prompt or tool config improvements\n\n---\n\n### Use Case 3: \"Memory Not Working\"\n\n**User says:** \"Agent doesn't remember things\"\n\n**Steps:**\n1. Search for memory operations:\n   ```bash\n   langsmith-fetch traces --last-n-minutes 10 --limit 20 --format raw | grep -i \"memory\\|recall\\|store\"\n   ```\n\n2. Check:\n   - Were memory tools called?\n   - Did recall return results?\n   - Were memories actually stored?\n   - Are retrieved memories being used?\n\n---\n\n### Use Case 4: \"Performance Issues\"\n\n**User says:** \"Agent is too slow\"\n\n**Steps:**\n1. Export with metadata:\n   ```bash\n   langsmith-fetch traces ./perf-analysis --last-n-minutes 30 --limit 50 --include-metadata\n   ```\n\n2. Analyze:\n   - Execution time per trace\n   - Tool call latencies\n   - Token usage (context size)\n   - Number of iterations\n   - Slowest operations\n\n3. Identify bottlenecks and suggest optimizations\n\n---\n\n## Output Format Guide\n\n### Pretty Format (Default)\n```bash\nlangsmith-fetch traces --limit 5 --format pretty\n```\n**Use for:** Quick visual inspection, showing to users\n\n### JSON Format\n```bash\nlangsmith-fetch traces --limit 5 --format json\n```\n**Use for:** Detailed analysis, syntax-highlighted review\n\n### Raw Format\n```bash\nlangsmith-fetch traces --limit 5 --format raw\n```\n**Use for:** Piping to other commands, automation\n\n---\n\n## Advanced Features\n\n### Time-Based Filtering\n```bash\n# After specific timestamp\nlangsmith-fetch traces --after \"2025-12-24T13:00:00Z\" --limit 20\n\n# Last N minutes (most common)\nlangsmith-fetch traces --last-n-minutes 60 --limit 100\n```\n\n### Include Metadata\n```bash\n# Get extra context\nlangsmith-fetch traces --limit 10 --include-metadata\n\n# Metadata includes: agent type, model, tags, environment\n```\n\n### Concurrent Fetching (Faster)\n```bash\n# Speed up large exports\nlangsmith-fetch traces ./output --limit 100 --concurrent 10\n```\n\n---\n\n## Troubleshooting\n\n### \"No traces found matching criteria\"\n\n**Possible causes:**\n1. No agent activity in the timeframe\n2. Tracing is disabled\n3. Wrong project name\n4. API key issues\n\n**Solutions:**\n```bash\n# 1. Try longer timeframe\nlangsmith-fetch traces --last-n-minutes 1440 --limit 50\n\n# 2. Check environment\necho $LANGSMITH_API_KEY\necho $LANGSMITH_PROJECT\n\n# 3. Try fetching threads instead\nlangsmith-fetch threads --limit 10\n\n# 4. Verify tracing is enabled in your code\n# Check for: LANGCHAIN_TRACING_V2=true\n```\n\n### \"Project not found\"\n\n**Solution:**\n```bash\n# View current config\nlangsmith-fetch config show\n\n# Set correct project\nexport LANGSMITH_PROJECT=\"correct-project-name\"\n\n# Or configure permanently\nlangsmith-fetch config set project \"your-project-name\"\n```\n\n### Environment variables not persisting\n\n**Solution:**\n```bash\n# Add to shell config file (~/.bashrc or ~/.zshrc)\necho 'export LANGSMITH_API_KEY=\"your_key\"' >> ~/.bashrc\necho 'export LANGSMITH_PROJECT=\"your_project\"' >> ~/.bashrc\n\n# Reload shell config\nsource ~/.bashrc\n```\n\n---\n\n## Best Practices\n\n### 1. Regular Health Checks\n```bash\n# Quick check after making changes\nlangsmith-fetch traces --last-n-minutes 5 --limit 5\n```\n\n### 2. Organized Storage\n```\nlangsmith-debug/\n├── sessions/\n│   ├── 2025-12-24/\n│   └── 2025-12-25/\n├── error-cases/\n└── performance-tests/\n```\n\n### 3. Document Findings\nWhen you find bugs:\n1. Export the problematic trace\n2. Save to `error-cases/` folder\n3. Note what went wrong in a README\n4. Share trace ID with team\n\n### 4. Integration with Development\n```bash\n# Before committing code\nlangsmith-fetch traces --last-n-minutes 10 --limit 5\n\n# If errors found\nlangsmith-fetch trace <error-id> --format json > pre-commit-error.json\n```\n\n---\n\n## Quick Reference\n\n```bash\n# Most common commands\n\n# Quick debug\nlangsmith-fetch traces --last-n-minutes 5 --limit 5 --format pretty\n\n# Specific trace\nlangsmith-fetch trace <trace-id> --format pretty\n\n# Export session\nlangsmith-fetch traces ./debug-session --last-n-minutes 30 --limit 50\n\n# Find errors\nlangsmith-fetch traces --last-n-minutes 30 --limit 50 --format raw | grep -i error\n\n# With metadata\nlangsmith-fetch traces --limit 10 --include-metadata\n```\n\n---\n\n## Resources\n\n- **LangSmith Fetch CLI:** https://github.com/langchain-ai/langsmith-fetch\n- **LangSmith Studio:** https://smith.langchain.com/\n- **LangChain Docs:** https://docs.langchain.com/\n- **This Skill Repo:** https://github.com/OthmanAdi/langsmith-fetch-skill\n\n---\n\n## Notes for Claude\n\n- Always check if `langsmith-fetch` is installed before running commands\n- Verify environment variables are set\n- Use `--format pretty` for human-readable output\n- Use `--format json` when you need to parse and analyze data\n- When exporting sessions, create organized folder structures\n- Always provide clear analysis and actionable insights\n- If commands fail, help troubleshoot configuration issues\n\n---\n\n**Version:** 0.1.0\n**Author:** Ahmad Othman Ammar Adi\n**License:** MIT\n**Repository:** https://github.com/OthmanAdi/langsmith-fetch-skill\n"
  },
  {
    "path": "lead-research-assistant/SKILL.md",
    "content": "---\nname: lead-research-assistant\ndescription: Identifies high-quality leads for your product or service by analyzing your business, searching for target companies, and providing actionable contact strategies. Perfect for sales, business development, and marketing professionals.\n---\n\n# Lead Research Assistant\n\nThis skill helps you identify and qualify potential leads for your business by analyzing your product/service, understanding your ideal customer profile, and providing actionable outreach strategies.\n\n## When to Use This Skill\n\n- Finding potential customers or clients for your product/service\n- Building a list of companies to reach out to for partnerships\n- Identifying target accounts for sales outreach\n- Researching companies that match your ideal customer profile\n- Preparing for business development activities\n\n## What This Skill Does\n\n1. **Understands Your Business**: Analyzes your product/service, value proposition, and target market\n2. **Identifies Target Companies**: Finds companies that match your ideal customer profile based on:\n   - Industry and sector\n   - Company size and location\n   - Technology stack and tools they use\n   - Growth stage and funding\n   - Pain points your product solves\n3. **Prioritizes Leads**: Ranks companies based on fit score and relevance\n4. **Provides Contact Strategies**: Suggests how to approach each lead with personalized messaging\n5. **Enriches Data**: Gathers relevant information about decision-makers and company context\n\n## How to Use\n\n### Basic Usage\n\nSimply describe your product/service and what you're looking for:\n\n```\nI'm building [product description]. Find me 10 companies in [location/industry] \nthat would be good leads for this.\n```\n\n### With Your Codebase\n\nFor even better results, run this from your product's source code directory:\n\n```\nLook at what I'm building in this repository and identify the top 10 companies \nin [location/industry] that would benefit from this product.\n```\n\n### Advanced Usage\n\nFor more targeted research:\n\n```\nMy product: [description]\nIdeal customer profile:\n- Industry: [industry]\n- Company size: [size range]\n- Location: [location]\n- Current pain points: [pain points]\n- Technologies they use: [tech stack]\n\nFind me 20 qualified leads with contact strategies for each.\n```\n\n## Instructions\n\nWhen a user requests lead research:\n\n1. **Understand the Product/Service**\n   - If in a code directory, analyze the codebase to understand the product\n   - Ask clarifying questions about the value proposition\n   - Identify key features and benefits\n   - Understand what problems it solves\n\n2. **Define Ideal Customer Profile**\n   - Determine target industries and sectors\n   - Identify company size ranges\n   - Consider geographic preferences\n   - Understand relevant pain points\n   - Note any technology requirements\n\n3. **Research and Identify Leads**\n   - Search for companies matching the criteria\n   - Look for signals of need (job postings, tech stack, recent news)\n   - Consider growth indicators (funding, expansion, hiring)\n   - Identify companies with complementary products/services\n   - Check for budget indicators\n\n4. **Prioritize and Score**\n   - Create a fit score (1-10) for each lead\n   - Consider factors like:\n     - Alignment with ICP\n     - Signals of immediate need\n     - Budget availability\n     - Competitive landscape\n     - Timing indicators\n\n5. **Provide Actionable Output**\n   \n   For each lead, provide:\n   - **Company Name** and website\n   - **Why They're a Good Fit**: Specific reasons based on their business\n   - **Priority Score**: 1-10 with explanation\n   - **Decision Maker**: Role/title to target (e.g., \"VP of Engineering\")\n   - **Contact Strategy**: Personalized approach suggestions\n   - **Value Proposition**: How your product solves their specific problem\n   - **Conversation Starters**: Specific points to mention in outreach\n   - **LinkedIn URL**: If available, for easy connection\n\n6. **Format the Output**\n\n   Present results in a clear, scannable format:\n\n   ```markdown\n   # Lead Research Results\n   \n   ## Summary\n   - Total leads found: [X]\n   - High priority (8-10): [X]\n   - Medium priority (5-7): [X]\n   - Average fit score: [X]\n   \n   ---\n   \n   ## Lead 1: [Company Name]\n   \n   **Website**: [URL]\n   **Priority Score**: [X/10]\n   **Industry**: [Industry]\n   **Size**: [Employee count/revenue range]\n   \n   **Why They're a Good Fit**:\n   [2-3 specific reasons based on their business]\n   \n   **Target Decision Maker**: [Role/Title]\n   **LinkedIn**: [URL if available]\n   \n   **Value Proposition for Them**:\n   [Specific benefit for this company]\n   \n   **Outreach Strategy**:\n   [Personalized approach - mention specific pain points, recent company news, or relevant context]\n   \n   **Conversation Starters**:\n   - [Specific point 1]\n   - [Specific point 2]\n   \n   ---\n   \n   [Repeat for each lead]\n   ```\n\n7. **Offer Next Steps**\n   - Suggest saving results to a CSV for CRM import\n   - Offer to draft personalized outreach messages\n   - Recommend prioritization based on timing\n   - Suggest follow-up research for top leads\n\n## Examples\n\n### Example 1: From Lenny's Newsletter\n\n**User**: \"I'm building a tool that masks sensitive data in AI coding assistant queries. Find potential leads.\"\n\n**Output**: Creates a prioritized list of companies that:\n- Use AI coding assistants (Copilot, Cursor, etc.)\n- Handle sensitive data (fintech, healthcare, legal)\n- Have evidence in their GitHub repos of using coding agents\n- May have accidentally exposed sensitive data in code\n- Includes LinkedIn URLs of relevant decision-makers\n\n### Example 2: Local Business\n\n**User**: \"I run a consulting practice for remote team productivity. Find me 10 companies in the Bay Area that recently went remote.\"\n\n**Output**: Identifies companies that:\n- Recently posted remote job listings\n- Announced remote-first policies\n- Are hiring distributed teams\n- Show signs of remote work challenges\n- Provides personalized outreach strategies for each\n\n## Tips for Best Results\n\n- **Be specific** about your product and its unique value\n- **Run from your codebase** if applicable for automatic context\n- **Provide context** about your ideal customer profile\n- **Specify constraints** like industry, location, or company size\n- **Request follow-up** research on promising leads for deeper insights\n\n## Related Use Cases\n\n- Drafting personalized outreach emails after identifying leads\n- Building a CRM-ready CSV of qualified prospects\n- Researching specific companies in detail\n- Analyzing competitor customer bases\n- Identifying partnership opportunities\n"
  },
  {
    "path": "mcp-builder/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "mcp-builder/SKILL.md",
    "content": "---\nname: mcp-builder\ndescription: Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).\nlicense: Complete terms in LICENSE.txt\n---\n\n# MCP Server Development Guide\n\n## Overview\n\nTo create high-quality MCP (Model Context Protocol) servers that enable LLMs to effectively interact with external services, use this skill. An MCP server provides tools that allow LLMs to access external services and APIs. The quality of an MCP server is measured by how well it enables LLMs to accomplish real-world tasks using the tools provided.\n\n---\n\n# Process\n\n## 🚀 High-Level Workflow\n\nCreating a high-quality MCP server involves four main phases:\n\n### Phase 1: Deep Research and Planning\n\n#### 1.1 Understand Agent-Centric Design Principles\n\nBefore diving into implementation, understand how to design tools for AI agents by reviewing these principles:\n\n**Build for Workflows, Not Just API Endpoints:**\n- Don't simply wrap existing API endpoints - build thoughtful, high-impact workflow tools\n- Consolidate related operations (e.g., `schedule_event` that both checks availability and creates event)\n- Focus on tools that enable complete tasks, not just individual API calls\n- Consider what workflows agents actually need to accomplish\n\n**Optimize for Limited Context:**\n- Agents have constrained context windows - make every token count\n- Return high-signal information, not exhaustive data dumps\n- Provide \"concise\" vs \"detailed\" response format options\n- Default to human-readable identifiers over technical codes (names over IDs)\n- Consider the agent's context budget as a scarce resource\n\n**Design Actionable Error Messages:**\n- Error messages should guide agents toward correct usage patterns\n- Suggest specific next steps: \"Try using filter='active_only' to reduce results\"\n- Make errors educational, not just diagnostic\n- Help agents learn proper tool usage through clear feedback\n\n**Follow Natural Task Subdivisions:**\n- Tool names should reflect how humans think about tasks\n- Group related tools with consistent prefixes for discoverability\n- Design tools around natural workflows, not just API structure\n\n**Use Evaluation-Driven Development:**\n- Create realistic evaluation scenarios early\n- Let agent feedback drive tool improvements\n- Prototype quickly and iterate based on actual agent performance\n\n#### 1.3 Study MCP Protocol Documentation\n\n**Fetch the latest MCP protocol documentation:**\n\nUse WebFetch to load: `https://modelcontextprotocol.io/llms-full.txt`\n\nThis comprehensive document contains the complete MCP specification and guidelines.\n\n#### 1.4 Study Framework Documentation\n\n**Load and read the following reference files:**\n\n- **MCP Best Practices**: [📋 View Best Practices](./reference/mcp_best_practices.md) - Core guidelines for all MCP servers\n\n**For Python implementations, also load:**\n- **Python SDK Documentation**: Use WebFetch to load `https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n- [🐍 Python Implementation Guide](./reference/python_mcp_server.md) - Python-specific best practices and examples\n\n**For Node/TypeScript implementations, also load:**\n- **TypeScript SDK Documentation**: Use WebFetch to load `https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/README.md`\n- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples\n\n#### 1.5 Exhaustively Study API Documentation\n\nTo integrate a service, read through **ALL** available API documentation:\n- Official API reference documentation\n- Authentication and authorization requirements\n- Rate limiting and pagination patterns\n- Error responses and status codes\n- Available endpoints and their parameters\n- Data models and schemas\n\n**To gather comprehensive information, use web search and the WebFetch tool as needed.**\n\n#### 1.6 Create a Comprehensive Implementation Plan\n\nBased on your research, create a detailed plan that includes:\n\n**Tool Selection:**\n- List the most valuable endpoints/operations to implement\n- Prioritize tools that enable the most common and important use cases\n- Consider which tools work together to enable complex workflows\n\n**Shared Utilities and Helpers:**\n- Identify common API request patterns\n- Plan pagination helpers\n- Design filtering and formatting utilities\n- Plan error handling strategies\n\n**Input/Output Design:**\n- Define input validation models (Pydantic for Python, Zod for TypeScript)\n- Design consistent response formats (e.g., JSON or Markdown), and configurable levels of detail (e.g., Detailed or Concise)\n- Plan for large-scale usage (thousands of users/resources)\n- Implement character limits and truncation strategies (e.g., 25,000 tokens)\n\n**Error Handling Strategy:**\n- Plan graceful failure modes\n- Design clear, actionable, LLM-friendly, natural language error messages which prompt further action\n- Consider rate limiting and timeout scenarios\n- Handle authentication and authorization errors\n\n---\n\n### Phase 2: Implementation\n\nNow that you have a comprehensive plan, begin implementation following language-specific best practices.\n\n#### 2.1 Set Up Project Structure\n\n**For Python:**\n- Create a single `.py` file or organize into modules if complex (see [🐍 Python Guide](./reference/python_mcp_server.md))\n- Use the MCP Python SDK for tool registration\n- Define Pydantic models for input validation\n\n**For Node/TypeScript:**\n- Create proper project structure (see [⚡ TypeScript Guide](./reference/node_mcp_server.md))\n- Set up `package.json` and `tsconfig.json`\n- Use MCP TypeScript SDK\n- Define Zod schemas for input validation\n\n#### 2.2 Implement Core Infrastructure First\n\n**To begin implementation, create shared utilities before implementing tools:**\n- API request helper functions\n- Error handling utilities\n- Response formatting functions (JSON and Markdown)\n- Pagination helpers\n- Authentication/token management\n\n#### 2.3 Implement Tools Systematically\n\nFor each tool in the plan:\n\n**Define Input Schema:**\n- Use Pydantic (Python) or Zod (TypeScript) for validation\n- Include proper constraints (min/max length, regex patterns, min/max values, ranges)\n- Provide clear, descriptive field descriptions\n- Include diverse examples in field descriptions\n\n**Write Comprehensive Docstrings/Descriptions:**\n- One-line summary of what the tool does\n- Detailed explanation of purpose and functionality\n- Explicit parameter types with examples\n- Complete return type schema\n- Usage examples (when to use, when not to use)\n- Error handling documentation, which outlines how to proceed given specific errors\n\n**Implement Tool Logic:**\n- Use shared utilities to avoid code duplication\n- Follow async/await patterns for all I/O\n- Implement proper error handling\n- Support multiple response formats (JSON and Markdown)\n- Respect pagination parameters\n- Check character limits and truncate appropriately\n\n**Add Tool Annotations:**\n- `readOnlyHint`: true (for read-only operations)\n- `destructiveHint`: false (for non-destructive operations)\n- `idempotentHint`: true (if repeated calls have same effect)\n- `openWorldHint`: true (if interacting with external systems)\n\n#### 2.4 Follow Language-Specific Best Practices\n\n**At this point, load the appropriate language guide:**\n\n**For Python: Load [🐍 Python Implementation Guide](./reference/python_mcp_server.md) and ensure the following:**\n- Using MCP Python SDK with proper tool registration\n- Pydantic v2 models with `model_config`\n- Type hints throughout\n- Async/await for all I/O operations\n- Proper imports organization\n- Module-level constants (CHARACTER_LIMIT, API_BASE_URL)\n\n**For Node/TypeScript: Load [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) and ensure the following:**\n- Using `server.registerTool` properly\n- Zod schemas with `.strict()`\n- TypeScript strict mode enabled\n- No `any` types - use proper types\n- Explicit Promise<T> return types\n- Build process configured (`npm run build`)\n\n---\n\n### Phase 3: Review and Refine\n\nAfter initial implementation:\n\n#### 3.1 Code Quality Review\n\nTo ensure quality, review the code for:\n- **DRY Principle**: No duplicated code between tools\n- **Composability**: Shared logic extracted into functions\n- **Consistency**: Similar operations return similar formats\n- **Error Handling**: All external calls have error handling\n- **Type Safety**: Full type coverage (Python type hints, TypeScript types)\n- **Documentation**: Every tool has comprehensive docstrings/descriptions\n\n#### 3.2 Test and Build\n\n**Important:** MCP servers are long-running processes that wait for requests over stdio/stdin or sse/http. Running them directly in your main process (e.g., `python server.py` or `node dist/index.js`) will cause your process to hang indefinitely.\n\n**Safe ways to test the server:**\n- Use the evaluation harness (see Phase 4) - recommended approach\n- Run the server in tmux to keep it outside your main process\n- Use a timeout when testing: `timeout 5s python server.py`\n\n**For Python:**\n- Verify Python syntax: `python -m py_compile your_server.py`\n- Check imports work correctly by reviewing the file\n- To manually test: Run server in tmux, then test with evaluation harness in main process\n- Or use the evaluation harness directly (it manages the server for stdio transport)\n\n**For Node/TypeScript:**\n- Run `npm run build` and ensure it completes without errors\n- Verify dist/index.js is created\n- To manually test: Run server in tmux, then test with evaluation harness in main process\n- Or use the evaluation harness directly (it manages the server for stdio transport)\n\n#### 3.3 Use Quality Checklist\n\nTo verify implementation quality, load the appropriate checklist from the language-specific guide:\n- Python: see \"Quality Checklist\" in [🐍 Python Guide](./reference/python_mcp_server.md)\n- Node/TypeScript: see \"Quality Checklist\" in [⚡ TypeScript Guide](./reference/node_mcp_server.md)\n\n---\n\n### Phase 4: Create Evaluations\n\nAfter implementing your MCP server, create comprehensive evaluations to test its effectiveness.\n\n**Load [✅ Evaluation Guide](./reference/evaluation.md) for complete evaluation guidelines.**\n\n#### 4.1 Understand Evaluation Purpose\n\nEvaluations test whether LLMs can effectively use your MCP server to answer realistic, complex questions.\n\n#### 4.2 Create 10 Evaluation Questions\n\nTo create effective evaluations, follow the process outlined in the evaluation guide:\n\n1. **Tool Inspection**: List available tools and understand their capabilities\n2. **Content Exploration**: Use READ-ONLY operations to explore available data\n3. **Question Generation**: Create 10 complex, realistic questions\n4. **Answer Verification**: Solve each question yourself to verify answers\n\n#### 4.3 Evaluation Requirements\n\nEach question must be:\n- **Independent**: Not dependent on other questions\n- **Read-only**: Only non-destructive operations required\n- **Complex**: Requiring multiple tool calls and deep exploration\n- **Realistic**: Based on real use cases humans would care about\n- **Verifiable**: Single, clear answer that can be verified by string comparison\n- **Stable**: Answer won't change over time\n\n#### 4.4 Output Format\n\nCreate an XML file with this structure:\n\n```xml\n<evaluation>\n  <qa_pair>\n    <question>Find discussions about AI model launches with animal codenames. One model needed a specific safety designation that uses the format ASL-X. What number X was being determined for the model named after a spotted wild cat?</question>\n    <answer>3</answer>\n  </qa_pair>\n<!-- More qa_pairs... -->\n</evaluation>\n```\n\n---\n\n# Reference Files\n\n## 📚 Documentation Library\n\nLoad these resources as needed during development:\n\n### Core MCP Documentation (Load First)\n- **MCP Protocol**: Fetch from `https://modelcontextprotocol.io/llms-full.txt` - Complete MCP specification\n- [📋 MCP Best Practices](./reference/mcp_best_practices.md) - Universal MCP guidelines including:\n  - Server and tool naming conventions\n  - Response format guidelines (JSON vs Markdown)\n  - Pagination best practices\n  - Character limits and truncation strategies\n  - Tool development guidelines\n  - Security and error handling standards\n\n### SDK Documentation (Load During Phase 1/2)\n- **Python SDK**: Fetch from `https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n- **TypeScript SDK**: Fetch from `https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/README.md`\n\n### Language-Specific Implementation Guides (Load During Phase 2)\n- [🐍 Python Implementation Guide](./reference/python_mcp_server.md) - Complete Python/FastMCP guide with:\n  - Server initialization patterns\n  - Pydantic model examples\n  - Tool registration with `@mcp.tool`\n  - Complete working examples\n  - Quality checklist\n\n- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Complete TypeScript guide with:\n  - Project structure\n  - Zod schema patterns\n  - Tool registration with `server.registerTool`\n  - Complete working examples\n  - Quality checklist\n\n### Evaluation Guide (Load During Phase 4)\n- [✅ Evaluation Guide](./reference/evaluation.md) - Complete evaluation creation guide with:\n  - Question creation guidelines\n  - Answer verification strategies\n  - XML format specifications\n  - Example questions and answers\n  - Running an evaluation with the provided scripts\n"
  },
  {
    "path": "mcp-builder/reference/evaluation.md",
    "content": "# MCP Server Evaluation Guide\n\n## Overview\n\nThis document provides guidance on creating comprehensive evaluations for MCP servers. Evaluations test whether LLMs can effectively use your MCP server to answer realistic, complex questions using only the tools provided.\n\n---\n\n## Quick Reference\n\n### Evaluation Requirements\n- Create 10 human-readable questions\n- Questions must be READ-ONLY, INDEPENDENT, NON-DESTRUCTIVE\n- Each question requires multiple tool calls (potentially dozens)\n- Answers must be single, verifiable values\n- Answers must be STABLE (won't change over time)\n\n### Output Format\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Your question here</question>\n      <answer>Single verifiable answer</answer>\n   </qa_pair>\n</evaluation>\n```\n\n---\n\n## Purpose of Evaluations\n\nThe measure of quality of an MCP server is NOT how well or comprehensively the server implements tools, but how well these implementations (input/output schemas, docstrings/descriptions, functionality) enable LLMs with no other context and access ONLY to the MCP servers to answer realistic and difficult questions.\n\n## Evaluation Overview\n\nCreate 10 human-readable questions requiring ONLY READ-ONLY, INDEPENDENT, NON-DESTRUCTIVE, and IDEMPOTENT operations to answer. Each question should be:\n- Realistic\n- Clear and concise\n- Unambiguous\n- Complex, requiring potentially dozens of tool calls or steps\n- Answerable with a single, verifiable value that you identify in advance\n\n## Question Guidelines\n\n### Core Requirements\n\n1. **Questions MUST be independent**\n   - Each question should NOT depend on the answer to any other question\n   - Should not assume prior write operations from processing another question\n\n2. **Questions MUST require ONLY NON-DESTRUCTIVE AND IDEMPOTENT tool use**\n   - Should not instruct or require modifying state to arrive at the correct answer\n\n3. **Questions must be REALISTIC, CLEAR, CONCISE, and COMPLEX**\n   - Must require another LLM to use multiple (potentially dozens of) tools or steps to answer\n\n### Complexity and Depth\n\n4. **Questions must require deep exploration**\n   - Consider multi-hop questions requiring multiple sub-questions and sequential tool calls\n   - Each step should benefit from information found in previous questions\n\n5. **Questions may require extensive paging**\n   - May need paging through multiple pages of results\n   - May require querying old data (1-2 years out-of-date) to find niche information\n   - The questions must be DIFFICULT\n\n6. **Questions must require deep understanding**\n   - Rather than surface-level knowledge\n   - May pose complex ideas as True/False questions requiring evidence\n   - May use multiple-choice format where LLM must search different hypotheses\n\n7. **Questions must not be solvable with straightforward keyword search**\n   - Do not include specific keywords from the target content\n   - Use synonyms, related concepts, or paraphrases\n   - Require multiple searches, analyzing multiple related items, extracting context, then deriving the answer\n\n### Tool Testing\n\n8. **Questions should stress-test tool return values**\n   - May elicit tools returning large JSON objects or lists, overwhelming the LLM\n   - Should require understanding multiple modalities of data:\n     - IDs and names\n     - Timestamps and datetimes (months, days, years, seconds)\n     - File IDs, names, extensions, and mimetypes\n     - URLs, GIDs, etc.\n   - Should probe the tool's ability to return all useful forms of data\n\n9. **Questions should MOSTLY reflect real human use cases**\n   - The kinds of information retrieval tasks that HUMANS assisted by an LLM would care about\n\n10. **Questions may require dozens of tool calls**\n    - This challenges LLMs with limited context\n    - Encourages MCP server tools to reduce information returned\n\n11. **Include ambiguous questions**\n    - May be ambiguous OR require difficult decisions on which tools to call\n    - Force the LLM to potentially make mistakes or misinterpret\n    - Ensure that despite AMBIGUITY, there is STILL A SINGLE VERIFIABLE ANSWER\n\n### Stability\n\n12. **Questions must be designed so the answer DOES NOT CHANGE**\n    - Do not ask questions that rely on \"current state\" which is dynamic\n    - For example, do not count:\n      - Number of reactions to a post\n      - Number of replies to a thread\n      - Number of members in a channel\n\n13. **DO NOT let the MCP server RESTRICT the kinds of questions you create**\n    - Create challenging and complex questions\n    - Some may not be solvable with the available MCP server tools\n    - Questions may require specific output formats (datetime vs. epoch time, JSON vs. MARKDOWN)\n    - Questions may require dozens of tool calls to complete\n\n## Answer Guidelines\n\n### Verification\n\n1. **Answers must be VERIFIABLE via direct string comparison**\n   - If the answer can be re-written in many formats, clearly specify the output format in the QUESTION\n   - Examples: \"Use YYYY/MM/DD.\", \"Respond True or False.\", \"Answer A, B, C, or D and nothing else.\"\n   - Answer should be a single VERIFIABLE value such as:\n     - User ID, user name, display name, first name, last name\n     - Channel ID, channel name\n     - Message ID, string\n     - URL, title\n     - Numerical quantity\n     - Timestamp, datetime\n     - Boolean (for True/False questions)\n     - Email address, phone number\n     - File ID, file name, file extension\n     - Multiple choice answer\n   - Answers must not require special formatting or complex, structured output\n   - Answer will be verified using DIRECT STRING COMPARISON\n\n### Readability\n\n2. **Answers should generally prefer HUMAN-READABLE formats**\n   - Examples: names, first name, last name, datetime, file name, message string, URL, yes/no, true/false, a/b/c/d\n   - Rather than opaque IDs (though IDs are acceptable)\n   - The VAST MAJORITY of answers should be human-readable\n\n### Stability\n\n3. **Answers must be STABLE/STATIONARY**\n   - Look at old content (e.g., conversations that have ended, projects that have launched, questions answered)\n   - Create QUESTIONS based on \"closed\" concepts that will always return the same answer\n   - Questions may ask to consider a fixed time window to insulate from non-stationary answers\n   - Rely on context UNLIKELY to change\n   - Example: if finding a paper name, be SPECIFIC enough so answer is not confused with papers published later\n\n4. **Answers must be CLEAR and UNAMBIGUOUS**\n   - Questions must be designed so there is a single, clear answer\n   - Answer can be derived from using the MCP server tools\n\n### Diversity\n\n5. **Answers must be DIVERSE**\n   - Answer should be a single VERIFIABLE value in diverse modalities and formats\n   - User concept: user ID, user name, display name, first name, last name, email address, phone number\n   - Channel concept: channel ID, channel name, channel topic\n   - Message concept: message ID, message string, timestamp, month, day, year\n\n6. **Answers must NOT be complex structures**\n   - Not a list of values\n   - Not a complex object\n   - Not a list of IDs or strings\n   - Not natural language text\n   - UNLESS the answer can be straightforwardly verified using DIRECT STRING COMPARISON\n   - And can be realistically reproduced\n   - It should be unlikely that an LLM would return the same list in any other order or format\n\n## Evaluation Process\n\n### Step 1: Documentation Inspection\n\nRead the documentation of the target API to understand:\n- Available endpoints and functionality\n- If ambiguity exists, fetch additional information from the web\n- Parallelize this step AS MUCH AS POSSIBLE\n- Ensure each subagent is ONLY examining documentation from the file system or on the web\n\n### Step 2: Tool Inspection\n\nList the tools available in the MCP server:\n- Inspect the MCP server directly\n- Understand input/output schemas, docstrings, and descriptions\n- WITHOUT calling the tools themselves at this stage\n\n### Step 3: Developing Understanding\n\nRepeat steps 1 & 2 until you have a good understanding:\n- Iterate multiple times\n- Think about the kinds of tasks you want to create\n- Refine your understanding\n- At NO stage should you READ the code of the MCP server implementation itself\n- Use your intuition and understanding to create reasonable, realistic, but VERY challenging tasks\n\n### Step 4: Read-Only Content Inspection\n\nAfter understanding the API and tools, USE the MCP server tools:\n- Inspect content using READ-ONLY and NON-DESTRUCTIVE operations ONLY\n- Goal: identify specific content (e.g., users, channels, messages, projects, tasks) for creating realistic questions\n- Should NOT call any tools that modify state\n- Will NOT read the code of the MCP server implementation itself\n- Parallelize this step with individual sub-agents pursuing independent explorations\n- Ensure each subagent is only performing READ-ONLY, NON-DESTRUCTIVE, and IDEMPOTENT operations\n- BE CAREFUL: SOME TOOLS may return LOTS OF DATA which would cause you to run out of CONTEXT\n- Make INCREMENTAL, SMALL, AND TARGETED tool calls for exploration\n- In all tool call requests, use the `limit` parameter to limit results (<10)\n- Use pagination\n\n### Step 5: Task Generation\n\nAfter inspecting the content, create 10 human-readable questions:\n- An LLM should be able to answer these with the MCP server\n- Follow all question and answer guidelines above\n\n## Output Format\n\nEach QA pair consists of a question and an answer. The output should be an XML file with this structure:\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the project created in Q2 2024 with the highest number of completed tasks. What is the project name?</question>\n      <answer>Website Redesign</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Search for issues labeled as \"bug\" that were closed in March 2024. Which user closed the most issues? Provide their username.</question>\n      <answer>sarah_dev</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Look for pull requests that modified files in the /api directory and were merged between January 1 and January 31, 2024. How many different contributors worked on these PRs?</question>\n      <answer>7</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Find the repository with the most stars that was created before 2023. What is the repository name?</question>\n      <answer>data-pipeline</answer>\n   </qa_pair>\n</evaluation>\n```\n\n## Evaluation Examples\n\n### Good Questions\n\n**Example 1: Multi-hop question requiring deep exploration (GitHub MCP)**\n```xml\n<qa_pair>\n   <question>Find the repository that was archived in Q3 2023 and had previously been the most forked project in the organization. What was the primary programming language used in that repository?</question>\n   <answer>Python</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires multiple searches to find archived repositories\n- Needs to identify which had the most forks before archival\n- Requires examining repository details for the language\n- Answer is a simple, verifiable value\n- Based on historical (closed) data that won't change\n\n**Example 2: Requires understanding context without keyword matching (Project Management MCP)**\n```xml\n<qa_pair>\n   <question>Locate the initiative focused on improving customer onboarding that was completed in late 2023. The project lead created a retrospective document after completion. What was the lead's role title at that time?</question>\n   <answer>Product Manager</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Doesn't use specific project name (\"initiative focused on improving customer onboarding\")\n- Requires finding completed projects from specific timeframe\n- Needs to identify the project lead and their role\n- Requires understanding context from retrospective documents\n- Answer is human-readable and stable\n- Based on completed work (won't change)\n\n**Example 3: Complex aggregation requiring multiple steps (Issue Tracker MCP)**\n```xml\n<qa_pair>\n   <question>Among all bugs reported in January 2024 that were marked as critical priority, which assignee resolved the highest percentage of their assigned bugs within 48 hours? Provide the assignee's username.</question>\n   <answer>alex_eng</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires filtering bugs by date, priority, and status\n- Needs to group by assignee and calculate resolution rates\n- Requires understanding timestamps to determine 48-hour windows\n- Tests pagination (potentially many bugs to process)\n- Answer is a single username\n- Based on historical data from specific time period\n\n**Example 4: Requires synthesis across multiple data types (CRM MCP)**\n```xml\n<qa_pair>\n   <question>Find the account that upgraded from the Starter to Enterprise plan in Q4 2023 and had the highest annual contract value. What industry does this account operate in?</question>\n   <answer>Healthcare</answer>\n</qa_pair>\n```\n\nThis question is good because:\n- Requires understanding subscription tier changes\n- Needs to identify upgrade events in specific timeframe\n- Requires comparing contract values\n- Must access account industry information\n- Answer is simple and verifiable\n- Based on completed historical transactions\n\n### Poor Questions\n\n**Example 1: Answer changes over time**\n```xml\n<qa_pair>\n   <question>How many open issues are currently assigned to the engineering team?</question>\n   <answer>47</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- The answer will change as issues are created, closed, or reassigned\n- Not based on stable/stationary data\n- Relies on \"current state\" which is dynamic\n\n**Example 2: Too easy with keyword search**\n```xml\n<qa_pair>\n   <question>Find the pull request with title \"Add authentication feature\" and tell me who created it.</question>\n   <answer>developer123</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- Can be solved with a straightforward keyword search for exact title\n- Doesn't require deep exploration or understanding\n- No synthesis or analysis needed\n\n**Example 3: Ambiguous answer format**\n```xml\n<qa_pair>\n   <question>List all the repositories that have Python as their primary language.</question>\n   <answer>repo1, repo2, repo3, data-pipeline, ml-tools</answer>\n</qa_pair>\n```\n\nThis question is poor because:\n- Answer is a list that could be returned in any order\n- Difficult to verify with direct string comparison\n- LLM might format differently (JSON array, comma-separated, newline-separated)\n- Better to ask for a specific aggregate (count) or superlative (most stars)\n\n## Verification Process\n\nAfter creating evaluations:\n\n1. **Examine the XML file** to understand the schema\n2. **Load each task instruction** and in parallel using the MCP server and tools, identify the correct answer by attempting to solve the task YOURSELF\n3. **Flag any operations** that require WRITE or DESTRUCTIVE operations\n4. **Accumulate all CORRECT answers** and replace any incorrect answers in the document\n5. **Remove any `<qa_pair>`** that require WRITE or DESTRUCTIVE operations\n\nRemember to parallelize solving tasks to avoid running out of context, then accumulate all answers and make changes to the file at the end.\n\n## Tips for Creating Quality Evaluations\n\n1. **Think Hard and Plan Ahead** before generating tasks\n2. **Parallelize Where Opportunity Arises** to speed up the process and manage context\n3. **Focus on Realistic Use Cases** that humans would actually want to accomplish\n4. **Create Challenging Questions** that test the limits of the MCP server's capabilities\n5. **Ensure Stability** by using historical data and closed concepts\n6. **Verify Answers** by solving the questions yourself using the MCP server tools\n7. **Iterate and Refine** based on what you learn during the process\n\n---\n\n# Running Evaluations\n\nAfter creating your evaluation file, you can use the provided evaluation harness to test your MCP server.\n\n## Setup\n\n1. **Install Dependencies**\n\n   ```bash\n   pip install -r scripts/requirements.txt\n   ```\n\n   Or install manually:\n   ```bash\n   pip install anthropic mcp\n   ```\n\n2. **Set API Key**\n\n   ```bash\n   export ANTHROPIC_API_KEY=your_api_key_here\n   ```\n\n## Evaluation File Format\n\nEvaluation files use XML format with `<qa_pair>` elements:\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the project created in Q2 2024 with the highest number of completed tasks. What is the project name?</question>\n      <answer>Website Redesign</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Search for issues labeled as \"bug\" that were closed in March 2024. Which user closed the most issues? Provide their username.</question>\n      <answer>sarah_dev</answer>\n   </qa_pair>\n</evaluation>\n```\n\n## Running Evaluations\n\nThe evaluation script (`scripts/evaluation.py`) supports three transport types:\n\n**Important:**\n- **stdio transport**: The evaluation script automatically launches and manages the MCP server process for you. Do not run the server manually.\n- **sse/http transports**: You must start the MCP server separately before running the evaluation. The script connects to the already-running server at the specified URL.\n\n### 1. Local STDIO Server\n\nFor locally-run MCP servers (script launches the server automatically):\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_mcp_server.py \\\n  evaluation.xml\n```\n\nWith environment variables:\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_mcp_server.py \\\n  -e API_KEY=abc123 \\\n  -e DEBUG=true \\\n  evaluation.xml\n```\n\n### 2. Server-Sent Events (SSE)\n\nFor SSE-based MCP servers (you must start the server first):\n\n```bash\npython scripts/evaluation.py \\\n  -t sse \\\n  -u https://example.com/mcp \\\n  -H \"Authorization: Bearer token123\" \\\n  -H \"X-Custom-Header: value\" \\\n  evaluation.xml\n```\n\n### 3. HTTP (Streamable HTTP)\n\nFor HTTP-based MCP servers (you must start the server first):\n\n```bash\npython scripts/evaluation.py \\\n  -t http \\\n  -u https://example.com/mcp \\\n  -H \"Authorization: Bearer token123\" \\\n  evaluation.xml\n```\n\n## Command-Line Options\n\n```\nusage: evaluation.py [-h] [-t {stdio,sse,http}] [-m MODEL] [-c COMMAND]\n                     [-a ARGS [ARGS ...]] [-e ENV [ENV ...]] [-u URL]\n                     [-H HEADERS [HEADERS ...]] [-o OUTPUT]\n                     eval_file\n\npositional arguments:\n  eval_file             Path to evaluation XML file\n\noptional arguments:\n  -h, --help            Show help message\n  -t, --transport       Transport type: stdio, sse, or http (default: stdio)\n  -m, --model           Claude model to use (default: claude-3-7-sonnet-20250219)\n  -o, --output          Output file for report (default: print to stdout)\n\nstdio options:\n  -c, --command         Command to run MCP server (e.g., python, node)\n  -a, --args            Arguments for the command (e.g., server.py)\n  -e, --env             Environment variables in KEY=VALUE format\n\nsse/http options:\n  -u, --url             MCP server URL\n  -H, --header          HTTP headers in 'Key: Value' format\n```\n\n## Output\n\nThe evaluation script generates a detailed report including:\n\n- **Summary Statistics**:\n  - Accuracy (correct/total)\n  - Average task duration\n  - Average tool calls per task\n  - Total tool calls\n\n- **Per-Task Results**:\n  - Prompt and expected response\n  - Actual response from the agent\n  - Whether the answer was correct (✅/❌)\n  - Duration and tool call details\n  - Agent's summary of its approach\n  - Agent's feedback on the tools\n\n### Save Report to File\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a my_server.py \\\n  -o evaluation_report.md \\\n  evaluation.xml\n```\n\n## Complete Example Workflow\n\nHere's a complete example of creating and running an evaluation:\n\n1. **Create your evaluation file** (`my_evaluation.xml`):\n\n```xml\n<evaluation>\n   <qa_pair>\n      <question>Find the user who created the most issues in January 2024. What is their username?</question>\n      <answer>alice_developer</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Among all pull requests merged in Q1 2024, which repository had the highest number? Provide the repository name.</question>\n      <answer>backend-api</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Find the project that was completed in December 2023 and had the longest duration from start to finish. How many days did it take?</question>\n      <answer>127</answer>\n   </qa_pair>\n</evaluation>\n```\n\n2. **Install dependencies**:\n\n```bash\npip install -r scripts/requirements.txt\nexport ANTHROPIC_API_KEY=your_api_key\n```\n\n3. **Run evaluation**:\n\n```bash\npython scripts/evaluation.py \\\n  -t stdio \\\n  -c python \\\n  -a github_mcp_server.py \\\n  -e GITHUB_TOKEN=ghp_xxx \\\n  -o github_eval_report.md \\\n  my_evaluation.xml\n```\n\n4. **Review the report** in `github_eval_report.md` to:\n   - See which questions passed/failed\n   - Read the agent's feedback on your tools\n   - Identify areas for improvement\n   - Iterate on your MCP server design\n\n## Troubleshooting\n\n### Connection Errors\n\nIf you get connection errors:\n- **STDIO**: Verify the command and arguments are correct\n- **SSE/HTTP**: Check the URL is accessible and headers are correct\n- Ensure any required API keys are set in environment variables or headers\n\n### Low Accuracy\n\nIf many evaluations fail:\n- Review the agent's feedback for each task\n- Check if tool descriptions are clear and comprehensive\n- Verify input parameters are well-documented\n- Consider whether tools return too much or too little data\n- Ensure error messages are actionable\n\n### Timeout Issues\n\nIf tasks are timing out:\n- Use a more capable model (e.g., `claude-3-7-sonnet-20250219`)\n- Check if tools are returning too much data\n- Verify pagination is working correctly\n- Consider simplifying complex questions"
  },
  {
    "path": "mcp-builder/reference/mcp_best_practices.md",
    "content": "# MCP Server Development Best Practices and Guidelines\n\n## Overview\n\nThis document compiles essential best practices and guidelines for building Model Context Protocol (MCP) servers. It covers naming conventions, tool design, response formats, pagination, error handling, security, and compliance requirements.\n\n---\n\n## Quick Reference\n\n### Server Naming\n- **Python**: `{service}_mcp` (e.g., `slack_mcp`)\n- **Node/TypeScript**: `{service}-mcp-server` (e.g., `slack-mcp-server`)\n\n### Tool Naming\n- Use snake_case with service prefix\n- Format: `{service}_{action}_{resource}`\n- Example: `slack_send_message`, `github_create_issue`\n\n### Response Formats\n- Support both JSON and Markdown formats\n- JSON for programmatic processing\n- Markdown for human readability\n\n### Pagination\n- Always respect `limit` parameter\n- Return `has_more`, `next_offset`, `total_count`\n- Default to 20-50 items\n\n### Character Limits\n- Set CHARACTER_LIMIT constant (typically 25,000)\n- Truncate gracefully with clear messages\n- Provide guidance on filtering\n\n---\n\n## Table of Contents\n1. Server Naming Conventions\n2. Tool Naming and Design\n3. Response Format Guidelines\n4. Pagination Best Practices\n5. Character Limits and Truncation\n6. Tool Development Best Practices\n7. Transport Best Practices\n8. Testing Requirements\n9. OAuth and Security Best Practices\n10. Resource Management Best Practices\n11. Prompt Management Best Practices\n12. Error Handling Standards\n13. Documentation Requirements\n14. Compliance and Monitoring\n\n---\n\n## 1. Server Naming Conventions\n\nFollow these standardized naming patterns for MCP servers:\n\n**Python**: Use format `{service}_mcp` (lowercase with underscores)\n- Examples: `slack_mcp`, `github_mcp`, `jira_mcp`, `stripe_mcp`\n\n**Node/TypeScript**: Use format `{service}-mcp-server` (lowercase with hyphens)\n- Examples: `slack-mcp-server`, `github-mcp-server`, `jira-mcp-server`\n\nThe name should be:\n- General (not tied to specific features)\n- Descriptive of the service/API being integrated\n- Easy to infer from the task description\n- Without version numbers or dates\n\n---\n\n## 2. Tool Naming and Design\n\n### Tool Naming Best Practices\n\n1. **Use snake_case**: `search_users`, `create_project`, `get_channel_info`\n2. **Include service prefix**: Anticipate that your MCP server may be used alongside other MCP servers\n   - Use `slack_send_message` instead of just `send_message`\n   - Use `github_create_issue` instead of just `create_issue`\n   - Use `asana_list_tasks` instead of just `list_tasks`\n3. **Be action-oriented**: Start with verbs (get, list, search, create, etc.)\n4. **Be specific**: Avoid generic names that could conflict with other servers\n5. **Maintain consistency**: Use consistent naming patterns within your server\n\n### Tool Design Guidelines\n\n- Tool descriptions must narrowly and unambiguously describe functionality\n- Descriptions must precisely match actual functionality\n- Should not create confusion with other MCP servers\n- Should provide tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- Keep tool operations focused and atomic\n\n---\n\n## 3. Response Format Guidelines\n\nAll tools that return data should support multiple formats for flexibility:\n\n### JSON Format (`response_format=\"json\"`)\n- Machine-readable structured data\n- Include all available fields and metadata\n- Consistent field names and types\n- Suitable for programmatic processing\n- Use for when LLMs need to process data further\n\n### Markdown Format (`response_format=\"markdown\"`, typically default)\n- Human-readable formatted text\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format (e.g., \"2024-01-15 10:30:00 UTC\" instead of epoch)\n- Show display names with IDs in parentheses (e.g., \"@john.doe (U123456)\")\n- Omit verbose metadata (e.g., show only one profile image URL, not all sizes)\n- Group related information logically\n- Use for when presenting information to users\n\n---\n\n## 4. Pagination Best Practices\n\nFor tools that list resources:\n\n- **Always respect the `limit` parameter**: Never load all results when a limit is specified\n- **Implement pagination**: Use `offset` or cursor-based pagination\n- **Return pagination metadata**: Include `has_more`, `next_offset`/`next_cursor`, `total_count`\n- **Never load all results into memory**: Especially important for large datasets\n- **Default to reasonable limits**: 20-50 items is typical\n- **Include clear pagination info in responses**: Make it easy for LLMs to request more data\n\nExample pagination response structure:\n```json\n{\n  \"total\": 150,\n  \"count\": 20,\n  \"offset\": 0,\n  \"items\": [...],\n  \"has_more\": true,\n  \"next_offset\": 20\n}\n```\n\n---\n\n## 5. Character Limits and Truncation\n\nTo prevent overwhelming responses with too much data:\n\n- **Define CHARACTER_LIMIT constant**: Typically 25,000 characters at module level\n- **Check response size before returning**: Measure the final response length\n- **Truncate gracefully with clear indicators**: Let the LLM know data was truncated\n- **Provide guidance on filtering**: Suggest how to use parameters to reduce results\n- **Include truncation metadata**: Show what was truncated and how to get more\n\nExample truncation handling:\n```python\nCHARACTER_LIMIT = 25000\n\nif len(result) > CHARACTER_LIMIT:\n    truncated_data = data[:max(1, len(data) // 2)]\n    response[\"truncated\"] = True\n    response[\"truncation_message\"] = (\n        f\"Response truncated from {len(data)} to {len(truncated_data)} items. \"\n        f\"Use 'offset' parameter or add filters to see more results.\"\n    )\n```\n\n---\n\n## 6. Transport Options\n\nMCP servers support multiple transport mechanisms for different deployment scenarios:\n\n### Stdio Transport\n\n**Best for**: Command-line tools, local integrations, subprocess execution\n\n**Characteristics**:\n- Standard input/output stream communication\n- Simple setup, no network configuration needed\n- Runs as a subprocess of the client\n- Ideal for desktop applications and CLI tools\n\n**Use when**:\n- Building tools for local development environments\n- Integrating with desktop applications (e.g., Claude Desktop)\n- Creating command-line utilities\n- Single-user, single-session scenarios\n\n### HTTP Transport\n\n**Best for**: Web services, remote access, multi-client scenarios\n\n**Characteristics**:\n- Request-response pattern over HTTP\n- Supports multiple simultaneous clients\n- Can be deployed as a web service\n- Requires network configuration and security considerations\n\n**Use when**:\n- Serving multiple clients simultaneously\n- Deploying as a cloud service\n- Integration with web applications\n- Need for load balancing or scaling\n\n### Server-Sent Events (SSE) Transport\n\n**Best for**: Real-time updates, push notifications, streaming data\n\n**Characteristics**:\n- One-way server-to-client streaming over HTTP\n- Enables real-time updates without polling\n- Long-lived connections for continuous data flow\n- Built on standard HTTP infrastructure\n\n**Use when**:\n- Clients need real-time data updates\n- Implementing push notifications\n- Streaming logs or monitoring data\n- Progressive result delivery for long operations\n\n### Transport Selection Criteria\n\n| Criterion | Stdio | HTTP | SSE |\n|-----------|-------|------|-----|\n| **Deployment** | Local | Remote | Remote |\n| **Clients** | Single | Multiple | Multiple |\n| **Communication** | Bidirectional | Request-Response | Server-Push |\n| **Complexity** | Low | Medium | Medium-High |\n| **Real-time** | No | No | Yes |\n\n---\n\n## 7. Tool Development Best Practices\n\n### General Guidelines\n1. Tool names should be descriptive and action-oriented\n2. Use parameter validation with detailed JSON schemas\n3. Include examples in tool descriptions\n4. Implement proper error handling and validation\n5. Use progress reporting for long operations\n6. Keep tool operations focused and atomic\n7. Document expected return value structures\n8. Implement proper timeouts\n9. Consider rate limiting for resource-intensive operations\n10. Log tool usage for debugging and monitoring\n\n### Security Considerations for Tools\n\n#### Input Validation\n- Validate all parameters against schema\n- Sanitize file paths and system commands\n- Validate URLs and external identifiers\n- Check parameter sizes and ranges\n- Prevent command injection\n\n#### Access Control\n- Implement authentication where needed\n- Use appropriate authorization checks\n- Audit tool usage\n- Rate limit requests\n- Monitor for abuse\n\n#### Error Handling\n- Don't expose internal errors to clients\n- Log security-relevant errors\n- Handle timeouts appropriately\n- Clean up resources after errors\n- Validate return values\n\n### Tool Annotations\n- Provide readOnlyHint and destructiveHint annotations\n- Remember annotations are hints, not security guarantees\n- Clients should not make security-critical decisions based solely on annotations\n\n---\n\n## 8. Transport Best Practices\n\n### General Transport Guidelines\n1. Handle connection lifecycle properly\n2. Implement proper error handling\n3. Use appropriate timeout values\n4. Implement connection state management\n5. Clean up resources on disconnection\n\n### Security Best Practices for Transport\n- Follow security considerations for DNS rebinding attacks\n- Implement proper authentication mechanisms\n- Validate message formats\n- Handle malformed messages gracefully\n\n### Stdio Transport Specific\n- Local MCP servers should NOT log to stdout (interferes with protocol)\n- Use stderr for logging messages\n- Handle standard I/O streams properly\n\n---\n\n## 9. Testing Requirements\n\nA comprehensive testing strategy should cover:\n\n### Functional Testing\n- Verify correct execution with valid/invalid inputs\n\n### Integration Testing\n- Test interaction with external systems\n\n### Security Testing\n- Validate auth, input sanitization, rate limiting\n\n### Performance Testing\n- Check behavior under load, timeouts\n\n### Error Handling\n- Ensure proper error reporting and cleanup\n\n---\n\n## 10. OAuth and Security Best Practices\n\n### Authentication and Authorization\n\nMCP servers that connect to external services should implement proper authentication:\n\n**OAuth 2.1 Implementation:**\n- Use secure OAuth 2.1 with certificates from recognized authorities\n- Validate access tokens before processing requests\n- Only accept tokens specifically intended for your server\n- Reject tokens without proper audience claims\n- Never pass through tokens received from MCP clients\n\n**API Key Management:**\n- Store API keys in environment variables, never in code\n- Validate keys on server startup\n- Provide clear error messages when authentication fails\n- Use secure transmission for sensitive credentials\n\n### Input Validation and Security\n\n**Always validate inputs:**\n- Sanitize file paths to prevent directory traversal\n- Validate URLs and external identifiers\n- Check parameter sizes and ranges\n- Prevent command injection in system calls\n- Use schema validation (Pydantic/Zod) for all inputs\n\n**Error handling security:**\n- Don't expose internal errors to clients\n- Log security-relevant errors server-side\n- Provide helpful but not revealing error messages\n- Clean up resources after errors\n\n### Privacy and Data Protection\n\n**Data collection principles:**\n- Only collect data strictly necessary for functionality\n- Don't collect extraneous conversation data\n- Don't collect PII unless explicitly required for the tool's purpose\n- Provide clear information about what data is accessed\n\n**Data transmission:**\n- Don't send data to servers outside your organization without disclosure\n- Use secure transmission (HTTPS) for all network communication\n- Validate certificates for external services\n\n---\n\n## 11. Resource Management Best Practices\n\n1. Only suggest necessary resources\n2. Use clear, descriptive names for roots\n3. Handle resource boundaries properly\n4. Respect client control over resources\n5. Use model-controlled primitives (tools) for automatic data exposure\n\n---\n\n## 12. Prompt Management Best Practices\n\n- Clients should show users proposed prompts\n- Users should be able to modify or reject prompts\n- Clients should show users completions\n- Users should be able to modify or reject completions\n- Consider costs when using sampling\n\n---\n\n## 13. Error Handling Standards\n\n- Use standard JSON-RPC error codes\n- Report tool errors within result objects (not protocol-level)\n- Provide helpful, specific error messages\n- Don't expose internal implementation details\n- Clean up resources properly on errors\n\n---\n\n## 14. Documentation Requirements\n\n- Provide clear documentation of all tools and capabilities\n- Include working examples (at least 3 per major feature)\n- Document security considerations\n- Specify required permissions and access levels\n- Document rate limits and performance characteristics\n\n---\n\n## 15. Compliance and Monitoring\n\n- Implement logging for debugging and monitoring\n- Track tool usage patterns\n- Monitor for potential abuse\n- Maintain audit trails for security-relevant operations\n- Be prepared for ongoing compliance reviews\n\n---\n\n## Summary\n\nThese best practices represent the comprehensive guidelines for building secure, efficient, and compliant MCP servers that work well within the ecosystem. Developers should follow these guidelines to ensure their MCP servers meet the standards for inclusion in the MCP directory and provide a safe, reliable experience for users.\n\n\n----------\n\n\n# Tools\n\n> Enable LLMs to perform actions through your server\n\nTools are a powerful primitive in the Model Context Protocol (MCP) that enable servers to expose executable functionality to clients. Through tools, LLMs can interact with external systems, perform computations, and take actions in the real world.\n\n<Note>\n  Tools are designed to be **model-controlled**, meaning that tools are exposed from servers to clients with the intention of the AI model being able to automatically invoke them (with a human in the loop to grant approval).\n</Note>\n\n## Overview\n\nTools in MCP allow servers to expose executable functions that can be invoked by clients and used by LLMs to perform actions. Key aspects of tools include:\n\n* **Discovery**: Clients can obtain a list of available tools by sending a `tools/list` request\n* **Invocation**: Tools are called using the `tools/call` request, where servers perform the requested operation and return results\n* **Flexibility**: Tools can range from simple calculations to complex API interactions\n\nLike [resources](/docs/concepts/resources), tools are identified by unique names and can include descriptions to guide their usage. However, unlike resources, tools represent dynamic operations that can modify state or interact with external systems.\n\n## Tool definition structure\n\nEach tool is defined with the following structure:\n\n```typescript\n{\n  name: string;          // Unique identifier for the tool\n  description?: string;  // Human-readable description\n  inputSchema: {         // JSON Schema for the tool's parameters\n    type: \"object\",\n    properties: { ... }  // Tool-specific parameters\n  },\n  annotations?: {        // Optional hints about tool behavior\n    title?: string;      // Human-readable title for the tool\n    readOnlyHint?: boolean;    // If true, the tool does not modify its environment\n    destructiveHint?: boolean; // If true, the tool may perform destructive updates\n    idempotentHint?: boolean;  // If true, repeated calls with same args have no additional effect\n    openWorldHint?: boolean;   // If true, tool interacts with external entities\n  }\n}\n```\n\n## Implementing tools\n\nHere's an example of implementing a basic tool in an MCP server:\n\n<Tabs>\n  <Tab title=\"TypeScript\">\n    ```typescript\n    const server = new Server({\n      name: \"example-server\",\n      version: \"1.0.0\"\n    }, {\n      capabilities: {\n        tools: {}\n      }\n    });\n\n    // Define available tools\n    server.setRequestHandler(ListToolsRequestSchema, async () => {\n      return {\n        tools: [{\n          name: \"calculate_sum\",\n          description: \"Add two numbers together\",\n          inputSchema: {\n            type: \"object\",\n            properties: {\n              a: { type: \"number\" },\n              b: { type: \"number\" }\n            },\n            required: [\"a\", \"b\"]\n          }\n        }]\n      };\n    });\n\n    // Handle tool execution\n    server.setRequestHandler(CallToolRequestSchema, async (request) => {\n      if (request.params.name === \"calculate_sum\") {\n        const { a, b } = request.params.arguments;\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: String(a + b)\n            }\n          ]\n        };\n      }\n      throw new Error(\"Tool not found\");\n    });\n    ```\n  </Tab>\n\n  <Tab title=\"Python\">\n    ```python\n    app = Server(\"example-server\")\n\n    @app.list_tools()\n    async def list_tools() -> list[types.Tool]:\n        return [\n            types.Tool(\n                name=\"calculate_sum\",\n                description=\"Add two numbers together\",\n                inputSchema={\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"a\": {\"type\": \"number\"},\n                        \"b\": {\"type\": \"number\"}\n                    },\n                    \"required\": [\"a\", \"b\"]\n                }\n            )\n        ]\n\n    @app.call_tool()\n    async def call_tool(\n        name: str,\n        arguments: dict\n    ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:\n        if name == \"calculate_sum\":\n            a = arguments[\"a\"]\n            b = arguments[\"b\"]\n            result = a + b\n            return [types.TextContent(type=\"text\", text=str(result))]\n        raise ValueError(f\"Tool not found: {name}\")\n    ```\n  </Tab>\n</Tabs>\n\n## Example tool patterns\n\nHere are some examples of types of tools that a server could provide:\n\n### System operations\n\nTools that interact with the local system:\n\n```typescript\n{\n  name: \"execute_command\",\n  description: \"Run a shell command\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      command: { type: \"string\" },\n      args: { type: \"array\", items: { type: \"string\" } }\n    }\n  }\n}\n```\n\n### API integrations\n\nTools that wrap external APIs:\n\n```typescript\n{\n  name: \"github_create_issue\",\n  description: \"Create a GitHub issue\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      title: { type: \"string\" },\n      body: { type: \"string\" },\n      labels: { type: \"array\", items: { type: \"string\" } }\n    }\n  }\n}\n```\n\n### Data processing\n\nTools that transform or analyze data:\n\n```typescript\n{\n  name: \"analyze_csv\",\n  description: \"Analyze a CSV file\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      filepath: { type: \"string\" },\n      operations: {\n        type: \"array\",\n        items: {\n          enum: [\"sum\", \"average\", \"count\"]\n        }\n      }\n    }\n  }\n}\n```\n\n## Best practices\n\nWhen implementing tools:\n\n1. Provide clear, descriptive names and descriptions\n2. Use detailed JSON Schema definitions for parameters\n3. Include examples in tool descriptions to demonstrate how the model should use them\n4. Implement proper error handling and validation\n5. Use progress reporting for long operations\n6. Keep tool operations focused and atomic\n7. Document expected return value structures\n8. Implement proper timeouts\n9. Consider rate limiting for resource-intensive operations\n10. Log tool usage for debugging and monitoring\n\n### Tool name conflicts\n\nMCP client applications and MCP server proxies may encounter tool name conflicts when building their own tool lists. For example, two connected MCP servers `web1` and `web2` may both expose a tool named `search_web`.\n\nApplications may disambiguiate tools with one of the following strategies (among others; not an exhaustive list):\n\n* Concatenating a unique, user-defined server name with the tool name, e.g. `web1___search_web` and `web2___search_web`. This strategy may be preferable when unique server names are already provided by the user in a configuration file.\n* Generating a random prefix for the tool name, e.g. `jrwxs___search_web` and `6cq52___search_web`. This strategy may be preferable in server proxies where user-defined unique names are not available.\n* Using the server URI as a prefix for the tool name, e.g. `web1.example.com:search_web` and `web2.example.com:search_web`. This strategy may be suitable when working with remote MCP servers.\n\nNote that the server-provided name from the initialization flow is not guaranteed to be unique and is not generally suitable for disambiguation purposes.\n\n## Security considerations\n\nWhen exposing tools:\n\n### Input validation\n\n* Validate all parameters against the schema\n* Sanitize file paths and system commands\n* Validate URLs and external identifiers\n* Check parameter sizes and ranges\n* Prevent command injection\n\n### Access control\n\n* Implement authentication where needed\n* Use appropriate authorization checks\n* Audit tool usage\n* Rate limit requests\n* Monitor for abuse\n\n### Error handling\n\n* Don't expose internal errors to clients\n* Log security-relevant errors\n* Handle timeouts appropriately\n* Clean up resources after errors\n* Validate return values\n\n## Tool discovery and updates\n\nMCP supports dynamic tool discovery:\n\n1. Clients can list available tools at any time\n2. Servers can notify clients when tools change using `notifications/tools/list_changed`\n3. Tools can be added or removed during runtime\n4. Tool definitions can be updated (though this should be done carefully)\n\n## Error handling\n\nTool errors should be reported within the result object, not as MCP protocol-level errors. This allows the LLM to see and potentially handle the error. When a tool encounters an error:\n\n1. Set `isError` to `true` in the result\n2. Include error details in the `content` array\n\nHere's an example of proper error handling for tools:\n\n<Tabs>\n  <Tab title=\"TypeScript\">\n    ```typescript\n    try {\n      // Tool operation\n      const result = performOperation();\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Operation successful: ${result}`\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        isError: true,\n        content: [\n          {\n            type: \"text\",\n            text: `Error: ${error.message}`\n          }\n        ]\n      };\n    }\n    ```\n  </Tab>\n\n  <Tab title=\"Python\">\n    ```python\n    try:\n        # Tool operation\n        result = perform_operation()\n        return types.CallToolResult(\n            content=[\n                types.TextContent(\n                    type=\"text\",\n                    text=f\"Operation successful: {result}\"\n                )\n            ]\n        )\n    except Exception as error:\n        return types.CallToolResult(\n            isError=True,\n            content=[\n                types.TextContent(\n                    type=\"text\",\n                    text=f\"Error: {str(error)}\"\n                )\n            ]\n        )\n    ```\n  </Tab>\n</Tabs>\n\nThis approach allows the LLM to see that an error occurred and potentially take corrective action or request human intervention.\n\n## Tool annotations\n\nTool annotations provide additional metadata about a tool's behavior, helping clients understand how to present and manage tools. These annotations are hints that describe the nature and impact of a tool, but should not be relied upon for security decisions.\n\n### Purpose of tool annotations\n\nTool annotations serve several key purposes:\n\n1. Provide UX-specific information without affecting model context\n2. Help clients categorize and present tools appropriately\n3. Convey information about a tool's potential side effects\n4. Assist in developing intuitive interfaces for tool approval\n\n### Available tool annotations\n\nThe MCP specification defines the following annotations for tools:\n\n| Annotation        | Type    | Default | Description                                                                                                                          |\n| ----------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |\n| `title`           | string  | -       | A human-readable title for the tool, useful for UI display                                                                           |\n| `readOnlyHint`    | boolean | false   | If true, indicates the tool does not modify its environment                                                                          |\n| `destructiveHint` | boolean | true    | If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false)                                     |\n| `idempotentHint`  | boolean | false   | If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false) |\n| `openWorldHint`   | boolean | true    | If true, the tool may interact with an \"open world\" of external entities                                                             |\n\n### Example usage\n\nHere's how to define tools with annotations for different scenarios:\n\n```typescript\n// A read-only search tool\n{\n  name: \"web_search\",\n  description: \"Search the web for information\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      query: { type: \"string\" }\n    },\n    required: [\"query\"]\n  },\n  annotations: {\n    title: \"Web Search\",\n    readOnlyHint: true,\n    openWorldHint: true\n  }\n}\n\n// A destructive file deletion tool\n{\n  name: \"delete_file\",\n  description: \"Delete a file from the filesystem\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      path: { type: \"string\" }\n    },\n    required: [\"path\"]\n  },\n  annotations: {\n    title: \"Delete File\",\n    readOnlyHint: false,\n    destructiveHint: true,\n    idempotentHint: true,\n    openWorldHint: false\n  }\n}\n\n// A non-destructive database record creation tool\n{\n  name: \"create_record\",\n  description: \"Create a new record in the database\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      table: { type: \"string\" },\n      data: { type: \"object\" }\n    },\n    required: [\"table\", \"data\"]\n  },\n  annotations: {\n    title: \"Create Database Record\",\n    readOnlyHint: false,\n    destructiveHint: false,\n    idempotentHint: false,\n    openWorldHint: false\n  }\n}\n```\n\n### Integrating annotations in server implementation\n\n<Tabs>\n  <Tab title=\"TypeScript\">\n    ```typescript\n    server.setRequestHandler(ListToolsRequestSchema, async () => {\n      return {\n        tools: [{\n          name: \"calculate_sum\",\n          description: \"Add two numbers together\",\n          inputSchema: {\n            type: \"object\",\n            properties: {\n              a: { type: \"number\" },\n              b: { type: \"number\" }\n            },\n            required: [\"a\", \"b\"]\n          },\n          annotations: {\n            title: \"Calculate Sum\",\n            readOnlyHint: true,\n            openWorldHint: false\n          }\n        }]\n      };\n    });\n    ```\n  </Tab>\n\n  <Tab title=\"Python\">\n    ```python\n    from mcp.server.fastmcp import FastMCP\n\n    mcp = FastMCP(\"example-server\")\n\n    @mcp.tool(\n        annotations={\n            \"title\": \"Calculate Sum\",\n            \"readOnlyHint\": True,\n            \"openWorldHint\": False\n        }\n    )\n    async def calculate_sum(a: float, b: float) -> str:\n        \"\"\"Add two numbers together.\n\n        Args:\n            a: First number to add\n            b: Second number to add\n        \"\"\"\n        result = a + b\n        return str(result)\n    ```\n  </Tab>\n</Tabs>\n\n### Best practices for tool annotations\n\n1. **Be accurate about side effects**: Clearly indicate whether a tool modifies its environment and whether those modifications are destructive.\n\n2. **Use descriptive titles**: Provide human-friendly titles that clearly describe the tool's purpose.\n\n3. **Indicate idempotency properly**: Mark tools as idempotent only if repeated calls with the same arguments truly have no additional effect.\n\n4. **Set appropriate open/closed world hints**: Indicate whether a tool interacts with a closed system (like a database) or an open system (like the web).\n\n5. **Remember annotations are hints**: All properties in ToolAnnotations are hints and not guaranteed to provide a faithful description of tool behavior. Clients should never make security-critical decisions based solely on annotations.\n\n## Testing tools\n\nA comprehensive testing strategy for MCP tools should cover:\n\n* **Functional testing**: Verify tools execute correctly with valid inputs and handle invalid inputs appropriately\n* **Integration testing**: Test tool interaction with external systems using both real and mocked dependencies\n* **Security testing**: Validate authentication, authorization, input sanitization, and rate limiting\n* **Performance testing**: Check behavior under load, timeout handling, and resource cleanup\n* **Error handling**: Ensure tools properly report errors through the MCP protocol and clean up resources\n"
  },
  {
    "path": "mcp-builder/reference/node_mcp_server.md",
    "content": "# Node/TypeScript MCP Server Implementation Guide\n\n## Overview\n\nThis document provides Node/TypeScript-specific best practices and examples for implementing MCP servers using the MCP TypeScript SDK. It covers project structure, server setup, tool registration patterns, input validation with Zod, error handling, and complete working examples.\n\n---\n\n## Quick Reference\n\n### Key Imports\n```typescript\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport axios, { AxiosError } from \"axios\";\n```\n\n### Server Initialization\n```typescript\nconst server = new McpServer({\n  name: \"service-mcp-server\",\n  version: \"1.0.0\"\n});\n```\n\n### Tool Registration Pattern\n```typescript\nserver.registerTool(\"tool_name\", {...config}, async (params) => {\n  // Implementation\n});\n```\n\n---\n\n## MCP TypeScript SDK\n\nThe official MCP TypeScript SDK provides:\n- `McpServer` class for server initialization\n- `registerTool` method for tool registration\n- Zod schema integration for runtime input validation\n- Type-safe tool handler implementations\n\nSee the MCP SDK documentation in the references for complete details.\n\n## Server Naming Convention\n\nNode/TypeScript MCP servers must follow this naming pattern:\n- **Format**: `{service}-mcp-server` (lowercase with hyphens)\n- **Examples**: `github-mcp-server`, `jira-mcp-server`, `stripe-mcp-server`\n\nThe name should be:\n- General (not tied to specific features)\n- Descriptive of the service/API being integrated\n- Easy to infer from the task description\n- Without version numbers or dates\n\n## Project Structure\n\nCreate the following structure for Node/TypeScript MCP servers:\n\n```\n{service}-mcp-server/\n├── package.json\n├── tsconfig.json\n├── README.md\n├── src/\n│   ├── index.ts          # Main entry point with McpServer initialization\n│   ├── types.ts          # TypeScript type definitions and interfaces\n│   ├── tools/            # Tool implementations (one file per domain)\n│   ├── services/         # API clients and shared utilities\n│   ├── schemas/          # Zod validation schemas\n│   └── constants.ts      # Shared constants (API_URL, CHARACTER_LIMIT, etc.)\n└── dist/                 # Built JavaScript files (entry point: dist/index.js)\n```\n\n## Tool Implementation\n\n### Tool Naming\n\nUse snake_case for tool names (e.g., \"search_users\", \"create_project\", \"get_channel_info\") with clear, action-oriented names.\n\n**Avoid Naming Conflicts**: Include the service context to prevent overlaps:\n- Use \"slack_send_message\" instead of just \"send_message\"\n- Use \"github_create_issue\" instead of just \"create_issue\"\n- Use \"asana_list_tasks\" instead of just \"list_tasks\"\n\n### Tool Structure\n\nTools are registered using the `registerTool` method with the following requirements:\n- Use Zod schemas for runtime input validation and type safety\n- The `description` field must be explicitly provided - JSDoc comments are NOT automatically extracted\n- Explicitly provide `title`, `description`, `inputSchema`, and `annotations`\n- The `inputSchema` must be a Zod schema object (not a JSON schema)\n- Type all parameters and return values explicitly\n\n```typescript\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nconst server = new McpServer({\n  name: \"example-mcp\",\n  version: \"1.0.0\"\n});\n\n// Zod schema for input validation\nconst UserSearchInputSchema = z.object({\n  query: z.string()\n    .min(2, \"Query must be at least 2 characters\")\n    .max(200, \"Query must not exceed 200 characters\")\n    .describe(\"Search string to match against names/emails\"),\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip for pagination\"),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n}).strict();\n\n// Type definition from Zod schema\ntype UserSearchInput = z.infer<typeof UserSearchInputSchema>;\n\nserver.registerTool(\n  \"example_search_users\",\n  {\n    title: \"Search Example Users\",\n    description: `Search for users in the Example system by name, email, or team.\n\nThis tool searches across all user profiles in the Example platform, supporting partial matches and various search filters. It does NOT create or modify users, only searches existing ones.\n\nArgs:\n  - query (string): Search string to match against names/emails\n  - limit (number): Maximum results to return, between 1-100 (default: 20)\n  - offset (number): Number of results to skip for pagination (default: 0)\n  - response_format ('markdown' | 'json'): Output format (default: 'markdown')\n\nReturns:\n  For JSON format: Structured data with schema:\n  {\n    \"total\": number,           // Total number of matches found\n    \"count\": number,           // Number of results in this response\n    \"offset\": number,          // Current pagination offset\n    \"users\": [\n      {\n        \"id\": string,          // User ID (e.g., \"U123456789\")\n        \"name\": string,        // Full name (e.g., \"John Doe\")\n        \"email\": string,       // Email address\n        \"team\": string,        // Team name (optional)\n        \"active\": boolean      // Whether user is active\n      }\n    ],\n    \"has_more\": boolean,       // Whether more results are available\n    \"next_offset\": number      // Offset for next page (if has_more is true)\n  }\n\nExamples:\n  - Use when: \"Find all marketing team members\" -> params with query=\"team:marketing\"\n  - Use when: \"Search for John's account\" -> params with query=\"john\"\n  - Don't use when: You need to create a user (use example_create_user instead)\n\nError Handling:\n  - Returns \"Error: Rate limit exceeded\" if too many requests (429 status)\n  - Returns \"No users found matching '<query>'\" if search returns empty`,\n    inputSchema: UserSearchInputSchema,\n    annotations: {\n      readOnlyHint: true,\n      destructiveHint: false,\n      idempotentHint: true,\n      openWorldHint: true\n    }\n  },\n  async (params: UserSearchInput) => {\n    try {\n      // Input validation is handled by Zod schema\n      // Make API request using validated parameters\n      const data = await makeApiRequest<any>(\n        \"users/search\",\n        \"GET\",\n        undefined,\n        {\n          q: params.query,\n          limit: params.limit,\n          offset: params.offset\n        }\n      );\n\n      const users = data.users || [];\n      const total = data.total || 0;\n\n      if (!users.length) {\n        return {\n          content: [{\n            type: \"text\",\n            text: `No users found matching '${params.query}'`\n          }]\n        };\n      }\n\n      // Format response based on requested format\n      let result: string;\n\n      if (params.response_format === ResponseFormat.MARKDOWN) {\n        // Human-readable markdown format\n        const lines: string[] = [`# User Search Results: '${params.query}'`, \"\"];\n        lines.push(`Found ${total} users (showing ${users.length})`);\n        lines.push(\"\");\n\n        for (const user of users) {\n          lines.push(`## ${user.name} (${user.id})`);\n          lines.push(`- **Email**: ${user.email}`);\n          if (user.team) {\n            lines.push(`- **Team**: ${user.team}`);\n          }\n          lines.push(\"\");\n        }\n\n        result = lines.join(\"\\n\");\n\n      } else {\n        // Machine-readable JSON format\n        const response: any = {\n          total,\n          count: users.length,\n          offset: params.offset,\n          users: users.map((user: any) => ({\n            id: user.id,\n            name: user.name,\n            email: user.email,\n            ...(user.team ? { team: user.team } : {}),\n            active: user.active ?? true\n          }))\n        };\n\n        // Add pagination info if there are more results\n        if (total > params.offset + users.length) {\n          response.has_more = true;\n          response.next_offset = params.offset + users.length;\n        }\n\n        result = JSON.stringify(response, null, 2);\n      }\n\n      return {\n        content: [{\n          type: \"text\",\n          text: result\n        }]\n      };\n    } catch (error) {\n      return {\n        content: [{\n          type: \"text\",\n          text: handleApiError(error)\n        }]\n      };\n    }\n  }\n);\n```\n\n## Zod Schemas for Input Validation\n\nZod provides runtime type validation:\n\n```typescript\nimport { z } from \"zod\";\n\n// Basic schema with validation\nconst CreateUserSchema = z.object({\n  name: z.string()\n    .min(1, \"Name is required\")\n    .max(100, \"Name must not exceed 100 characters\"),\n  email: z.string()\n    .email(\"Invalid email format\"),\n  age: z.number()\n    .int(\"Age must be a whole number\")\n    .min(0, \"Age cannot be negative\")\n    .max(150, \"Age cannot be greater than 150\")\n}).strict();  // Use .strict() to forbid extra fields\n\n// Enums\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\nconst SearchSchema = z.object({\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format\")\n});\n\n// Optional fields with defaults\nconst PaginationSchema = z.object({\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip\")\n});\n```\n\n## Response Format Options\n\nSupport multiple output formats for flexibility:\n\n```typescript\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\nconst inputSchema = z.object({\n  query: z.string(),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n});\n```\n\n**Markdown format**:\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format\n- Show display names with IDs in parentheses\n- Omit verbose metadata\n- Group related information logically\n\n**JSON format**:\n- Return complete, structured data suitable for programmatic processing\n- Include all available fields and metadata\n- Use consistent field names and types\n\n## Pagination Implementation\n\nFor tools that list resources:\n\n```typescript\nconst ListSchema = z.object({\n  limit: z.number().int().min(1).max(100).default(20),\n  offset: z.number().int().min(0).default(0)\n});\n\nasync function listItems(params: z.infer<typeof ListSchema>) {\n  const data = await apiRequest(params.limit, params.offset);\n\n  const response = {\n    total: data.total,\n    count: data.items.length,\n    offset: params.offset,\n    items: data.items,\n    has_more: data.total > params.offset + data.items.length,\n    next_offset: data.total > params.offset + data.items.length\n      ? params.offset + data.items.length\n      : undefined\n  };\n\n  return JSON.stringify(response, null, 2);\n}\n```\n\n## Character Limits and Truncation\n\nAdd a CHARACTER_LIMIT constant to prevent overwhelming responses:\n\n```typescript\n// At module level in constants.ts\nexport const CHARACTER_LIMIT = 25000;  // Maximum response size in characters\n\nasync function searchTool(params: SearchInput) {\n  let result = generateResponse(data);\n\n  // Check character limit and truncate if needed\n  if (result.length > CHARACTER_LIMIT) {\n    const truncatedData = data.slice(0, Math.max(1, data.length / 2));\n    response.data = truncatedData;\n    response.truncated = true;\n    response.truncation_message =\n      `Response truncated from ${data.length} to ${truncatedData.length} items. ` +\n      `Use 'offset' parameter or add filters to see more results.`;\n    result = JSON.stringify(response, null, 2);\n  }\n\n  return result;\n}\n```\n\n## Error Handling\n\nProvide clear, actionable error messages:\n\n```typescript\nimport axios, { AxiosError } from \"axios\";\n\nfunction handleApiError(error: unknown): string {\n  if (error instanceof AxiosError) {\n    if (error.response) {\n      switch (error.response.status) {\n        case 404:\n          return \"Error: Resource not found. Please check the ID is correct.\";\n        case 403:\n          return \"Error: Permission denied. You don't have access to this resource.\";\n        case 429:\n          return \"Error: Rate limit exceeded. Please wait before making more requests.\";\n        default:\n          return `Error: API request failed with status ${error.response.status}`;\n      }\n    } else if (error.code === \"ECONNABORTED\") {\n      return \"Error: Request timed out. Please try again.\";\n    }\n  }\n  return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;\n}\n```\n\n## Shared Utilities\n\nExtract common functionality into reusable functions:\n\n```typescript\n// Shared API request function\nasync function makeApiRequest<T>(\n  endpoint: string,\n  method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" = \"GET\",\n  data?: any,\n  params?: any\n): Promise<T> {\n  try {\n    const response = await axios({\n      method,\n      url: `${API_BASE_URL}/${endpoint}`,\n      data,\n      params,\n      timeout: 30000,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Accept\": \"application/json\"\n      }\n    });\n    return response.data;\n  } catch (error) {\n    throw error;\n  }\n}\n```\n\n## Async/Await Best Practices\n\nAlways use async/await for network requests and I/O operations:\n\n```typescript\n// Good: Async network request\nasync function fetchData(resourceId: string): Promise<ResourceData> {\n  const response = await axios.get(`${API_URL}/resource/${resourceId}`);\n  return response.data;\n}\n\n// Bad: Promise chains\nfunction fetchData(resourceId: string): Promise<ResourceData> {\n  return axios.get(`${API_URL}/resource/${resourceId}`)\n    .then(response => response.data);  // Harder to read and maintain\n}\n```\n\n## TypeScript Best Practices\n\n1. **Use Strict TypeScript**: Enable strict mode in tsconfig.json\n2. **Define Interfaces**: Create clear interface definitions for all data structures\n3. **Avoid `any`**: Use proper types or `unknown` instead of `any`\n4. **Zod for Runtime Validation**: Use Zod schemas to validate external data\n5. **Type Guards**: Create type guard functions for complex type checking\n6. **Error Handling**: Always use try-catch with proper error type checking\n7. **Null Safety**: Use optional chaining (`?.`) and nullish coalescing (`??`)\n\n```typescript\n// Good: Type-safe with Zod and interfaces\ninterface UserResponse {\n  id: string;\n  name: string;\n  email: string;\n  team?: string;\n  active: boolean;\n}\n\nconst UserSchema = z.object({\n  id: z.string(),\n  name: z.string(),\n  email: z.string().email(),\n  team: z.string().optional(),\n  active: z.boolean()\n});\n\ntype User = z.infer<typeof UserSchema>;\n\nasync function getUser(id: string): Promise<User> {\n  const data = await apiCall(`/users/${id}`);\n  return UserSchema.parse(data);  // Runtime validation\n}\n\n// Bad: Using any\nasync function getUser(id: string): Promise<any> {\n  return await apiCall(`/users/${id}`);  // No type safety\n}\n```\n\n## Package Configuration\n\n### package.json\n\n```json\n{\n  \"name\": \"{service}-mcp-server\",\n  \"version\": \"1.0.0\",\n  \"description\": \"MCP server for {Service} API integration\",\n  \"type\": \"module\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"start\": \"node dist/index.js\",\n    \"dev\": \"tsx watch src/index.ts\",\n    \"build\": \"tsc\",\n    \"clean\": \"rm -rf dist\"\n  },\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"dependencies\": {\n    \"@modelcontextprotocol/sdk\": \"^1.6.1\",\n    \"axios\": \"^1.7.9\",\n    \"zod\": \"^3.23.8\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.10.0\",\n    \"tsx\": \"^4.19.2\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n```\n\n### tsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"lib\": [\"ES2022\"],\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true,\n    \"allowSyntheticDefaultImports\": true\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n## Complete Example\n\n```typescript\n#!/usr/bin/env node\n/**\n * MCP Server for Example Service.\n *\n * This server provides tools to interact with Example API, including user search,\n * project management, and data export capabilities.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport axios, { AxiosError } from \"axios\";\n\n// Constants\nconst API_BASE_URL = \"https://api.example.com/v1\";\nconst CHARACTER_LIMIT = 25000;\n\n// Enums\nenum ResponseFormat {\n  MARKDOWN = \"markdown\",\n  JSON = \"json\"\n}\n\n// Zod schemas\nconst UserSearchInputSchema = z.object({\n  query: z.string()\n    .min(2, \"Query must be at least 2 characters\")\n    .max(200, \"Query must not exceed 200 characters\")\n    .describe(\"Search string to match against names/emails\"),\n  limit: z.number()\n    .int()\n    .min(1)\n    .max(100)\n    .default(20)\n    .describe(\"Maximum results to return\"),\n  offset: z.number()\n    .int()\n    .min(0)\n    .default(0)\n    .describe(\"Number of results to skip for pagination\"),\n  response_format: z.nativeEnum(ResponseFormat)\n    .default(ResponseFormat.MARKDOWN)\n    .describe(\"Output format: 'markdown' for human-readable or 'json' for machine-readable\")\n}).strict();\n\ntype UserSearchInput = z.infer<typeof UserSearchInputSchema>;\n\n// Shared utility functions\nasync function makeApiRequest<T>(\n  endpoint: string,\n  method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" = \"GET\",\n  data?: any,\n  params?: any\n): Promise<T> {\n  try {\n    const response = await axios({\n      method,\n      url: `${API_BASE_URL}/${endpoint}`,\n      data,\n      params,\n      timeout: 30000,\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Accept\": \"application/json\"\n      }\n    });\n    return response.data;\n  } catch (error) {\n    throw error;\n  }\n}\n\nfunction handleApiError(error: unknown): string {\n  if (error instanceof AxiosError) {\n    if (error.response) {\n      switch (error.response.status) {\n        case 404:\n          return \"Error: Resource not found. Please check the ID is correct.\";\n        case 403:\n          return \"Error: Permission denied. You don't have access to this resource.\";\n        case 429:\n          return \"Error: Rate limit exceeded. Please wait before making more requests.\";\n        default:\n          return `Error: API request failed with status ${error.response.status}`;\n      }\n    } else if (error.code === \"ECONNABORTED\") {\n      return \"Error: Request timed out. Please try again.\";\n    }\n  }\n  return `Error: Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`;\n}\n\n// Create MCP server instance\nconst server = new McpServer({\n  name: \"example-mcp\",\n  version: \"1.0.0\"\n});\n\n// Register tools\nserver.registerTool(\n  \"example_search_users\",\n  {\n    title: \"Search Example Users\",\n    description: `[Full description as shown above]`,\n    inputSchema: UserSearchInputSchema,\n    annotations: {\n      readOnlyHint: true,\n      destructiveHint: false,\n      idempotentHint: true,\n      openWorldHint: true\n    }\n  },\n  async (params: UserSearchInput) => {\n    // Implementation as shown above\n  }\n);\n\n// Main function\nasync function main() {\n  // Verify environment variables if needed\n  if (!process.env.EXAMPLE_API_KEY) {\n    console.error(\"ERROR: EXAMPLE_API_KEY environment variable is required\");\n    process.exit(1);\n  }\n\n  // Create transport\n  const transport = new StdioServerTransport();\n\n  // Connect server to transport\n  await server.connect(transport);\n\n  console.error(\"Example MCP server running via stdio\");\n}\n\n// Run the server\nmain().catch((error) => {\n  console.error(\"Server error:\", error);\n  process.exit(1);\n});\n```\n\n---\n\n## Advanced MCP Features\n\n### Resource Registration\n\nExpose data as resources for efficient, URI-based access:\n\n```typescript\nimport { ResourceTemplate } from \"@modelcontextprotocol/sdk/types.js\";\n\n// Register a resource with URI template\nserver.registerResource(\n  {\n    uri: \"file://documents/{name}\",\n    name: \"Document Resource\",\n    description: \"Access documents by name\",\n    mimeType: \"text/plain\"\n  },\n  async (uri: string) => {\n    // Extract parameter from URI\n    const match = uri.match(/^file:\\/\\/documents\\/(.+)$/);\n    if (!match) {\n      throw new Error(\"Invalid URI format\");\n    }\n\n    const documentName = match[1];\n    const content = await loadDocument(documentName);\n\n    return {\n      contents: [{\n        uri,\n        mimeType: \"text/plain\",\n        text: content\n      }]\n    };\n  }\n);\n\n// List available resources dynamically\nserver.registerResourceList(async () => {\n  const documents = await getAvailableDocuments();\n  return {\n    resources: documents.map(doc => ({\n      uri: `file://documents/${doc.name}`,\n      name: doc.name,\n      mimeType: \"text/plain\",\n      description: doc.description\n    }))\n  };\n});\n```\n\n**When to use Resources vs Tools:**\n- **Resources**: For data access with simple URI-based parameters\n- **Tools**: For complex operations requiring validation and business logic\n- **Resources**: When data is relatively static or template-based\n- **Tools**: When operations have side effects or complex workflows\n\n### Multiple Transport Options\n\nThe TypeScript SDK supports different transport mechanisms:\n\n```typescript\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\n\n// Stdio transport (default - for CLI tools)\nconst stdioTransport = new StdioServerTransport();\nawait server.connect(stdioTransport);\n\n// SSE transport (for real-time web updates)\nconst sseTransport = new SSEServerTransport(\"/message\", response);\nawait server.connect(sseTransport);\n\n// HTTP transport (for web services)\n// Configure based on your HTTP framework integration\n```\n\n**Transport selection guide:**\n- **Stdio**: Command-line tools, subprocess integration, local development\n- **HTTP**: Web services, remote access, multiple simultaneous clients\n- **SSE**: Real-time updates, server-push notifications, web dashboards\n\n### Notification Support\n\nNotify clients when server state changes:\n\n```typescript\n// Notify when tools list changes\nserver.notification({\n  method: \"notifications/tools/list_changed\"\n});\n\n// Notify when resources change\nserver.notification({\n  method: \"notifications/resources/list_changed\"\n});\n```\n\nUse notifications sparingly - only when server capabilities genuinely change.\n\n---\n\n## Code Best Practices\n\n### Code Composability and Reusability\n\nYour implementation MUST prioritize composability and code reuse:\n\n1. **Extract Common Functionality**:\n   - Create reusable helper functions for operations used across multiple tools\n   - Build shared API clients for HTTP requests instead of duplicating code\n   - Centralize error handling logic in utility functions\n   - Extract business logic into dedicated functions that can be composed\n   - Extract shared markdown or JSON field selection & formatting functionality\n\n2. **Avoid Duplication**:\n   - NEVER copy-paste similar code between tools\n   - If you find yourself writing similar logic twice, extract it into a function\n   - Common operations like pagination, filtering, field selection, and formatting should be shared\n   - Authentication/authorization logic should be centralized\n\n## Building and Running\n\nAlways build your TypeScript code before running:\n\n```bash\n# Build the project\nnpm run build\n\n# Run the server\nnpm start\n\n# Development with auto-reload\nnpm run dev\n```\n\nAlways ensure `npm run build` completes successfully before considering the implementation complete.\n\n## Quality Checklist\n\nBefore finalizing your Node/TypeScript MCP server implementation, ensure:\n\n### Strategic Design\n- [ ] Tools enable complete workflows, not just API endpoint wrappers\n- [ ] Tool names reflect natural task subdivisions\n- [ ] Response formats optimize for agent context efficiency\n- [ ] Human-readable identifiers used where appropriate\n- [ ] Error messages guide agents toward correct usage\n\n### Implementation Quality\n- [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented\n- [ ] All tools registered using `registerTool` with complete configuration\n- [ ] All tools include `title`, `description`, `inputSchema`, and `annotations`\n- [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- [ ] All tools use Zod schemas for runtime input validation with `.strict()` enforcement\n- [ ] All Zod schemas have proper constraints and descriptive error messages\n- [ ] All tools have comprehensive descriptions with explicit input/output types\n- [ ] Descriptions include return value examples and complete schema documentation\n- [ ] Error messages are clear, actionable, and educational\n\n### TypeScript Quality\n- [ ] TypeScript interfaces are defined for all data structures\n- [ ] Strict TypeScript is enabled in tsconfig.json\n- [ ] No use of `any` type - use `unknown` or proper types instead\n- [ ] All async functions have explicit Promise<T> return types\n- [ ] Error handling uses proper type guards (e.g., `axios.isAxiosError`, `z.ZodError`)\n\n### Advanced Features (where applicable)\n- [ ] Resources registered for appropriate data endpoints\n- [ ] Appropriate transport configured (stdio, HTTP, SSE)\n- [ ] Notifications implemented for dynamic server capabilities\n- [ ] Type-safe with SDK interfaces\n\n### Project Configuration\n- [ ] Package.json includes all necessary dependencies\n- [ ] Build script produces working JavaScript in dist/ directory\n- [ ] Main entry point is properly configured as dist/index.js\n- [ ] Server name follows format: `{service}-mcp-server`\n- [ ] tsconfig.json properly configured with strict mode\n\n### Code Quality\n- [ ] Pagination is properly implemented where applicable\n- [ ] Large responses check CHARACTER_LIMIT constant and truncate with clear messages\n- [ ] Filtering options are provided for potentially large result sets\n- [ ] All network operations handle timeouts and connection errors gracefully\n- [ ] Common functionality is extracted into reusable functions\n- [ ] Return types are consistent across similar operations\n\n### Testing and Build\n- [ ] `npm run build` completes successfully without errors\n- [ ] dist/index.js created and executable\n- [ ] Server runs: `node dist/index.js --help`\n- [ ] All imports resolve correctly\n- [ ] Sample tool calls work as expected"
  },
  {
    "path": "mcp-builder/reference/python_mcp_server.md",
    "content": "# Python MCP Server Implementation Guide\n\n## Overview\n\nThis document provides Python-specific best practices and examples for implementing MCP servers using the MCP Python SDK. It covers server setup, tool registration patterns, input validation with Pydantic, error handling, and complete working examples.\n\n---\n\n## Quick Reference\n\n### Key Imports\n```python\nfrom mcp.server.fastmcp import FastMCP\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\nfrom typing import Optional, List, Dict, Any\nfrom enum import Enum\nimport httpx\n```\n\n### Server Initialization\n```python\nmcp = FastMCP(\"service_mcp\")\n```\n\n### Tool Registration Pattern\n```python\n@mcp.tool(name=\"tool_name\", annotations={...})\nasync def tool_function(params: InputModel) -> str:\n    # Implementation\n    pass\n```\n\n---\n\n## MCP Python SDK and FastMCP\n\nThe official MCP Python SDK provides FastMCP, a high-level framework for building MCP servers. It provides:\n- Automatic description and inputSchema generation from function signatures and docstrings\n- Pydantic model integration for input validation\n- Decorator-based tool registration with `@mcp.tool`\n\n**For complete SDK documentation, use WebFetch to load:**\n`https://raw.githubusercontent.com/modelcontextprotocol/python-sdk/main/README.md`\n\n## Server Naming Convention\n\nPython MCP servers must follow this naming pattern:\n- **Format**: `{service}_mcp` (lowercase with underscores)\n- **Examples**: `github_mcp`, `jira_mcp`, `stripe_mcp`\n\nThe name should be:\n- General (not tied to specific features)\n- Descriptive of the service/API being integrated\n- Easy to infer from the task description\n- Without version numbers or dates\n\n## Tool Implementation\n\n### Tool Naming\n\nUse snake_case for tool names (e.g., \"search_users\", \"create_project\", \"get_channel_info\") with clear, action-oriented names.\n\n**Avoid Naming Conflicts**: Include the service context to prevent overlaps:\n- Use \"slack_send_message\" instead of just \"send_message\"\n- Use \"github_create_issue\" instead of just \"create_issue\"\n- Use \"asana_list_tasks\" instead of just \"list_tasks\"\n\n### Tool Structure with FastMCP\n\nTools are defined using the `@mcp.tool` decorator with Pydantic models for input validation:\n\n```python\nfrom pydantic import BaseModel, Field, ConfigDict\nfrom mcp.server.fastmcp import FastMCP\n\n# Initialize the MCP server\nmcp = FastMCP(\"example_mcp\")\n\n# Define Pydantic model for input validation\nclass ServiceToolInput(BaseModel):\n    '''Input model for service tool operation.'''\n    model_config = ConfigDict(\n        str_strip_whitespace=True,  # Auto-strip whitespace from strings\n        validate_assignment=True,    # Validate on assignment\n        extra='forbid'              # Forbid extra fields\n    )\n\n    param1: str = Field(..., description=\"First parameter description (e.g., 'user123', 'project-abc')\", min_length=1, max_length=100)\n    param2: Optional[int] = Field(default=None, description=\"Optional integer parameter with constraints\", ge=0, le=1000)\n    tags: Optional[List[str]] = Field(default_factory=list, description=\"List of tags to apply\", max_items=10)\n\n@mcp.tool(\n    name=\"service_tool_name\",\n    annotations={\n        \"title\": \"Human-Readable Tool Title\",\n        \"readOnlyHint\": True,     # Tool does not modify environment\n        \"destructiveHint\": False,  # Tool does not perform destructive operations\n        \"idempotentHint\": True,    # Repeated calls have no additional effect\n        \"openWorldHint\": False     # Tool does not interact with external entities\n    }\n)\nasync def service_tool_name(params: ServiceToolInput) -> str:\n    '''Tool description automatically becomes the 'description' field.\n\n    This tool performs a specific operation on the service. It validates all inputs\n    using the ServiceToolInput Pydantic model before processing.\n\n    Args:\n        params (ServiceToolInput): Validated input parameters containing:\n            - param1 (str): First parameter description\n            - param2 (Optional[int]): Optional parameter with default\n            - tags (Optional[List[str]]): List of tags\n\n    Returns:\n        str: JSON-formatted response containing operation results\n    '''\n    # Implementation here\n    pass\n```\n\n## Pydantic v2 Key Features\n\n- Use `model_config` instead of nested `Config` class\n- Use `field_validator` instead of deprecated `validator`\n- Use `model_dump()` instead of deprecated `dict()`\n- Validators require `@classmethod` decorator\n- Type hints are required for validator methods\n\n```python\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\n\nclass CreateUserInput(BaseModel):\n    model_config = ConfigDict(\n        str_strip_whitespace=True,\n        validate_assignment=True\n    )\n\n    name: str = Field(..., description=\"User's full name\", min_length=1, max_length=100)\n    email: str = Field(..., description=\"User's email address\", pattern=r'^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$')\n    age: int = Field(..., description=\"User's age\", ge=0, le=150)\n\n    @field_validator('email')\n    @classmethod\n    def validate_email(cls, v: str) -> str:\n        if not v.strip():\n            raise ValueError(\"Email cannot be empty\")\n        return v.lower()\n```\n\n## Response Format Options\n\nSupport multiple output formats for flexibility:\n\n```python\nfrom enum import Enum\n\nclass ResponseFormat(str, Enum):\n    '''Output format for tool responses.'''\n    MARKDOWN = \"markdown\"\n    JSON = \"json\"\n\nclass UserSearchInput(BaseModel):\n    query: str = Field(..., description=\"Search query\")\n    response_format: ResponseFormat = Field(\n        default=ResponseFormat.MARKDOWN,\n        description=\"Output format: 'markdown' for human-readable or 'json' for machine-readable\"\n    )\n```\n\n**Markdown format**:\n- Use headers, lists, and formatting for clarity\n- Convert timestamps to human-readable format (e.g., \"2024-01-15 10:30:00 UTC\" instead of epoch)\n- Show display names with IDs in parentheses (e.g., \"@john.doe (U123456)\")\n- Omit verbose metadata (e.g., show only one profile image URL, not all sizes)\n- Group related information logically\n\n**JSON format**:\n- Return complete, structured data suitable for programmatic processing\n- Include all available fields and metadata\n- Use consistent field names and types\n\n## Pagination Implementation\n\nFor tools that list resources:\n\n```python\nclass ListInput(BaseModel):\n    limit: Optional[int] = Field(default=20, description=\"Maximum results to return\", ge=1, le=100)\n    offset: Optional[int] = Field(default=0, description=\"Number of results to skip for pagination\", ge=0)\n\nasync def list_items(params: ListInput) -> str:\n    # Make API request with pagination\n    data = await api_request(limit=params.limit, offset=params.offset)\n\n    # Return pagination info\n    response = {\n        \"total\": data[\"total\"],\n        \"count\": len(data[\"items\"]),\n        \"offset\": params.offset,\n        \"items\": data[\"items\"],\n        \"has_more\": data[\"total\"] > params.offset + len(data[\"items\"]),\n        \"next_offset\": params.offset + len(data[\"items\"]) if data[\"total\"] > params.offset + len(data[\"items\"]) else None\n    }\n    return json.dumps(response, indent=2)\n```\n\n## Character Limits and Truncation\n\nAdd a CHARACTER_LIMIT constant to prevent overwhelming responses:\n\n```python\n# At module level\nCHARACTER_LIMIT = 25000  # Maximum response size in characters\n\nasync def search_tool(params: SearchInput) -> str:\n    result = generate_response(data)\n\n    # Check character limit and truncate if needed\n    if len(result) > CHARACTER_LIMIT:\n        # Truncate data and add notice\n        truncated_data = data[:max(1, len(data) // 2)]\n        response[\"data\"] = truncated_data\n        response[\"truncated\"] = True\n        response[\"truncation_message\"] = (\n            f\"Response truncated from {len(data)} to {len(truncated_data)} items. \"\n            f\"Use 'offset' parameter or add filters to see more results.\"\n        )\n        result = json.dumps(response, indent=2)\n\n    return result\n```\n\n## Error Handling\n\nProvide clear, actionable error messages:\n\n```python\ndef _handle_api_error(e: Exception) -> str:\n    '''Consistent error formatting across all tools.'''\n    if isinstance(e, httpx.HTTPStatusError):\n        if e.response.status_code == 404:\n            return \"Error: Resource not found. Please check the ID is correct.\"\n        elif e.response.status_code == 403:\n            return \"Error: Permission denied. You don't have access to this resource.\"\n        elif e.response.status_code == 429:\n            return \"Error: Rate limit exceeded. Please wait before making more requests.\"\n        return f\"Error: API request failed with status {e.response.status_code}\"\n    elif isinstance(e, httpx.TimeoutException):\n        return \"Error: Request timed out. Please try again.\"\n    return f\"Error: Unexpected error occurred: {type(e).__name__}\"\n```\n\n## Shared Utilities\n\nExtract common functionality into reusable functions:\n\n```python\n# Shared API request function\nasync def _make_api_request(endpoint: str, method: str = \"GET\", **kwargs) -> dict:\n    '''Reusable function for all API calls.'''\n    async with httpx.AsyncClient() as client:\n        response = await client.request(\n            method,\n            f\"{API_BASE_URL}/{endpoint}\",\n            timeout=30.0,\n            **kwargs\n        )\n        response.raise_for_status()\n        return response.json()\n```\n\n## Async/Await Best Practices\n\nAlways use async/await for network requests and I/O operations:\n\n```python\n# Good: Async network request\nasync def fetch_data(resource_id: str) -> dict:\n    async with httpx.AsyncClient() as client:\n        response = await client.get(f\"{API_URL}/resource/{resource_id}\")\n        response.raise_for_status()\n        return response.json()\n\n# Bad: Synchronous request\ndef fetch_data(resource_id: str) -> dict:\n    response = requests.get(f\"{API_URL}/resource/{resource_id}\")  # Blocks\n    return response.json()\n```\n\n## Type Hints\n\nUse type hints throughout:\n\n```python\nfrom typing import Optional, List, Dict, Any\n\nasync def get_user(user_id: str) -> Dict[str, Any]:\n    data = await fetch_user(user_id)\n    return {\"id\": data[\"id\"], \"name\": data[\"name\"]}\n```\n\n## Tool Docstrings\n\nEvery tool must have comprehensive docstrings with explicit type information:\n\n```python\nasync def search_users(params: UserSearchInput) -> str:\n    '''\n    Search for users in the Example system by name, email, or team.\n\n    This tool searches across all user profiles in the Example platform,\n    supporting partial matches and various search filters. It does NOT\n    create or modify users, only searches existing ones.\n\n    Args:\n        params (UserSearchInput): Validated input parameters containing:\n            - query (str): Search string to match against names/emails (e.g., \"john\", \"@example.com\", \"team:marketing\")\n            - limit (Optional[int]): Maximum results to return, between 1-100 (default: 20)\n            - offset (Optional[int]): Number of results to skip for pagination (default: 0)\n\n    Returns:\n        str: JSON-formatted string containing search results with the following schema:\n\n        Success response:\n        {\n            \"total\": int,           # Total number of matches found\n            \"count\": int,           # Number of results in this response\n            \"offset\": int,          # Current pagination offset\n            \"users\": [\n                {\n                    \"id\": str,      # User ID (e.g., \"U123456789\")\n                    \"name\": str,    # Full name (e.g., \"John Doe\")\n                    \"email\": str,   # Email address (e.g., \"john@example.com\")\n                    \"team\": str     # Team name (e.g., \"Marketing\") - optional\n                }\n            ]\n        }\n\n        Error response:\n        \"Error: <error message>\" or \"No users found matching '<query>'\"\n\n    Examples:\n        - Use when: \"Find all marketing team members\" -> params with query=\"team:marketing\"\n        - Use when: \"Search for John's account\" -> params with query=\"john\"\n        - Don't use when: You need to create a user (use example_create_user instead)\n        - Don't use when: You have a user ID and need full details (use example_get_user instead)\n\n    Error Handling:\n        - Input validation errors are handled by Pydantic model\n        - Returns \"Error: Rate limit exceeded\" if too many requests (429 status)\n        - Returns \"Error: Invalid API authentication\" if API key is invalid (401 status)\n        - Returns formatted list of results or \"No users found matching 'query'\"\n    '''\n```\n\n## Complete Example\n\nSee below for a complete Python MCP server example:\n\n```python\n#!/usr/bin/env python3\n'''\nMCP Server for Example Service.\n\nThis server provides tools to interact with Example API, including user search,\nproject management, and data export capabilities.\n'''\n\nfrom typing import Optional, List, Dict, Any\nfrom enum import Enum\nimport httpx\nfrom pydantic import BaseModel, Field, field_validator, ConfigDict\nfrom mcp.server.fastmcp import FastMCP\n\n# Initialize the MCP server\nmcp = FastMCP(\"example_mcp\")\n\n# Constants\nAPI_BASE_URL = \"https://api.example.com/v1\"\nCHARACTER_LIMIT = 25000  # Maximum response size in characters\n\n# Enums\nclass ResponseFormat(str, Enum):\n    '''Output format for tool responses.'''\n    MARKDOWN = \"markdown\"\n    JSON = \"json\"\n\n# Pydantic Models for Input Validation\nclass UserSearchInput(BaseModel):\n    '''Input model for user search operations.'''\n    model_config = ConfigDict(\n        str_strip_whitespace=True,\n        validate_assignment=True\n    )\n\n    query: str = Field(..., description=\"Search string to match against names/emails\", min_length=2, max_length=200)\n    limit: Optional[int] = Field(default=20, description=\"Maximum results to return\", ge=1, le=100)\n    offset: Optional[int] = Field(default=0, description=\"Number of results to skip for pagination\", ge=0)\n    response_format: ResponseFormat = Field(default=ResponseFormat.MARKDOWN, description=\"Output format\")\n\n    @field_validator('query')\n    @classmethod\n    def validate_query(cls, v: str) -> str:\n        if not v.strip():\n            raise ValueError(\"Query cannot be empty or whitespace only\")\n        return v.strip()\n\n# Shared utility functions\nasync def _make_api_request(endpoint: str, method: str = \"GET\", **kwargs) -> dict:\n    '''Reusable function for all API calls.'''\n    async with httpx.AsyncClient() as client:\n        response = await client.request(\n            method,\n            f\"{API_BASE_URL}/{endpoint}\",\n            timeout=30.0,\n            **kwargs\n        )\n        response.raise_for_status()\n        return response.json()\n\ndef _handle_api_error(e: Exception) -> str:\n    '''Consistent error formatting across all tools.'''\n    if isinstance(e, httpx.HTTPStatusError):\n        if e.response.status_code == 404:\n            return \"Error: Resource not found. Please check the ID is correct.\"\n        elif e.response.status_code == 403:\n            return \"Error: Permission denied. You don't have access to this resource.\"\n        elif e.response.status_code == 429:\n            return \"Error: Rate limit exceeded. Please wait before making more requests.\"\n        return f\"Error: API request failed with status {e.response.status_code}\"\n    elif isinstance(e, httpx.TimeoutException):\n        return \"Error: Request timed out. Please try again.\"\n    return f\"Error: Unexpected error occurred: {type(e).__name__}\"\n\n# Tool definitions\n@mcp.tool(\n    name=\"example_search_users\",\n    annotations={\n        \"title\": \"Search Example Users\",\n        \"readOnlyHint\": True,\n        \"destructiveHint\": False,\n        \"idempotentHint\": True,\n        \"openWorldHint\": True\n    }\n)\nasync def example_search_users(params: UserSearchInput) -> str:\n    '''Search for users in the Example system by name, email, or team.\n\n    [Full docstring as shown above]\n    '''\n    try:\n        # Make API request using validated parameters\n        data = await _make_api_request(\n            \"users/search\",\n            params={\n                \"q\": params.query,\n                \"limit\": params.limit,\n                \"offset\": params.offset\n            }\n        )\n\n        users = data.get(\"users\", [])\n        total = data.get(\"total\", 0)\n\n        if not users:\n            return f\"No users found matching '{params.query}'\"\n\n        # Format response based on requested format\n        if params.response_format == ResponseFormat.MARKDOWN:\n            lines = [f\"# User Search Results: '{params.query}'\", \"\"]\n            lines.append(f\"Found {total} users (showing {len(users)})\")\n            lines.append(\"\")\n\n            for user in users:\n                lines.append(f\"## {user['name']} ({user['id']})\")\n                lines.append(f\"- **Email**: {user['email']}\")\n                if user.get('team'):\n                    lines.append(f\"- **Team**: {user['team']}\")\n                lines.append(\"\")\n\n            return \"\\n\".join(lines)\n\n        else:\n            # Machine-readable JSON format\n            import json\n            response = {\n                \"total\": total,\n                \"count\": len(users),\n                \"offset\": params.offset,\n                \"users\": users\n            }\n            return json.dumps(response, indent=2)\n\n    except Exception as e:\n        return _handle_api_error(e)\n\nif __name__ == \"__main__\":\n    mcp.run()\n```\n\n---\n\n## Advanced FastMCP Features\n\n### Context Parameter Injection\n\nFastMCP can automatically inject a `Context` parameter into tools for advanced capabilities like logging, progress reporting, resource reading, and user interaction:\n\n```python\nfrom mcp.server.fastmcp import FastMCP, Context\n\nmcp = FastMCP(\"example_mcp\")\n\n@mcp.tool()\nasync def advanced_search(query: str, ctx: Context) -> str:\n    '''Advanced tool with context access for logging and progress.'''\n\n    # Report progress for long operations\n    await ctx.report_progress(0.25, \"Starting search...\")\n\n    # Log information for debugging\n    await ctx.log_info(\"Processing query\", {\"query\": query, \"timestamp\": datetime.now()})\n\n    # Perform search\n    results = await search_api(query)\n    await ctx.report_progress(0.75, \"Formatting results...\")\n\n    # Access server configuration\n    server_name = ctx.fastmcp.name\n\n    return format_results(results)\n\n@mcp.tool()\nasync def interactive_tool(resource_id: str, ctx: Context) -> str:\n    '''Tool that can request additional input from users.'''\n\n    # Request sensitive information when needed\n    api_key = await ctx.elicit(\n        prompt=\"Please provide your API key:\",\n        input_type=\"password\"\n    )\n\n    # Use the provided key\n    return await api_call(resource_id, api_key)\n```\n\n**Context capabilities:**\n- `ctx.report_progress(progress, message)` - Report progress for long operations\n- `ctx.log_info(message, data)` / `ctx.log_error()` / `ctx.log_debug()` - Logging\n- `ctx.elicit(prompt, input_type)` - Request input from users\n- `ctx.fastmcp.name` - Access server configuration\n- `ctx.read_resource(uri)` - Read MCP resources\n\n### Resource Registration\n\nExpose data as resources for efficient, template-based access:\n\n```python\n@mcp.resource(\"file://documents/{name}\")\nasync def get_document(name: str) -> str:\n    '''Expose documents as MCP resources.\n\n    Resources are useful for static or semi-static data that doesn't\n    require complex parameters. They use URI templates for flexible access.\n    '''\n    document_path = f\"./docs/{name}\"\n    with open(document_path, \"r\") as f:\n        return f.read()\n\n@mcp.resource(\"config://settings/{key}\")\nasync def get_setting(key: str, ctx: Context) -> str:\n    '''Expose configuration as resources with context.'''\n    settings = await load_settings()\n    return json.dumps(settings.get(key, {}))\n```\n\n**When to use Resources vs Tools:**\n- **Resources**: For data access with simple parameters (URI templates)\n- **Tools**: For complex operations with validation and business logic\n\n### Structured Output Types\n\nFastMCP supports multiple return types beyond strings:\n\n```python\nfrom typing import TypedDict\nfrom dataclasses import dataclass\nfrom pydantic import BaseModel\n\n# TypedDict for structured returns\nclass UserData(TypedDict):\n    id: str\n    name: str\n    email: str\n\n@mcp.tool()\nasync def get_user_typed(user_id: str) -> UserData:\n    '''Returns structured data - FastMCP handles serialization.'''\n    return {\"id\": user_id, \"name\": \"John Doe\", \"email\": \"john@example.com\"}\n\n# Pydantic models for complex validation\nclass DetailedUser(BaseModel):\n    id: str\n    name: str\n    email: str\n    created_at: datetime\n    metadata: Dict[str, Any]\n\n@mcp.tool()\nasync def get_user_detailed(user_id: str) -> DetailedUser:\n    '''Returns Pydantic model - automatically generates schema.'''\n    user = await fetch_user(user_id)\n    return DetailedUser(**user)\n```\n\n### Lifespan Management\n\nInitialize resources that persist across requests:\n\n```python\nfrom contextlib import asynccontextmanager\n\n@asynccontextmanager\nasync def app_lifespan():\n    '''Manage resources that live for the server's lifetime.'''\n    # Initialize connections, load config, etc.\n    db = await connect_to_database()\n    config = load_configuration()\n\n    # Make available to all tools\n    yield {\"db\": db, \"config\": config}\n\n    # Cleanup on shutdown\n    await db.close()\n\nmcp = FastMCP(\"example_mcp\", lifespan=app_lifespan)\n\n@mcp.tool()\nasync def query_data(query: str, ctx: Context) -> str:\n    '''Access lifespan resources through context.'''\n    db = ctx.request_context.lifespan_state[\"db\"]\n    results = await db.query(query)\n    return format_results(results)\n```\n\n### Multiple Transport Options\n\nFastMCP supports different transport mechanisms:\n\n```python\n# Default: Stdio transport (for CLI tools)\nif __name__ == \"__main__\":\n    mcp.run()\n\n# HTTP transport (for web services)\nif __name__ == \"__main__\":\n    mcp.run(transport=\"streamable_http\", port=8000)\n\n# SSE transport (for real-time updates)\nif __name__ == \"__main__\":\n    mcp.run(transport=\"sse\", port=8000)\n```\n\n**Transport selection:**\n- **Stdio**: Command-line tools, subprocess integration\n- **HTTP**: Web services, remote access, multiple clients\n- **SSE**: Real-time updates, push notifications\n\n---\n\n## Code Best Practices\n\n### Code Composability and Reusability\n\nYour implementation MUST prioritize composability and code reuse:\n\n1. **Extract Common Functionality**:\n   - Create reusable helper functions for operations used across multiple tools\n   - Build shared API clients for HTTP requests instead of duplicating code\n   - Centralize error handling logic in utility functions\n   - Extract business logic into dedicated functions that can be composed\n   - Extract shared markdown or JSON field selection & formatting functionality\n\n2. **Avoid Duplication**:\n   - NEVER copy-paste similar code between tools\n   - If you find yourself writing similar logic twice, extract it into a function\n   - Common operations like pagination, filtering, field selection, and formatting should be shared\n   - Authentication/authorization logic should be centralized\n\n### Python-Specific Best Practices\n\n1. **Use Type Hints**: Always include type annotations for function parameters and return values\n2. **Pydantic Models**: Define clear Pydantic models for all input validation\n3. **Avoid Manual Validation**: Let Pydantic handle input validation with constraints\n4. **Proper Imports**: Group imports (standard library, third-party, local)\n5. **Error Handling**: Use specific exception types (httpx.HTTPStatusError, not generic Exception)\n6. **Async Context Managers**: Use `async with` for resources that need cleanup\n7. **Constants**: Define module-level constants in UPPER_CASE\n\n## Quality Checklist\n\nBefore finalizing your Python MCP server implementation, ensure:\n\n### Strategic Design\n- [ ] Tools enable complete workflows, not just API endpoint wrappers\n- [ ] Tool names reflect natural task subdivisions\n- [ ] Response formats optimize for agent context efficiency\n- [ ] Human-readable identifiers used where appropriate\n- [ ] Error messages guide agents toward correct usage\n\n### Implementation Quality\n- [ ] FOCUSED IMPLEMENTATION: Most important and valuable tools implemented\n- [ ] All tools have descriptive names and documentation\n- [ ] Return types are consistent across similar operations\n- [ ] Error handling is implemented for all external calls\n- [ ] Server name follows format: `{service}_mcp`\n- [ ] All network operations use async/await\n- [ ] Common functionality is extracted into reusable functions\n- [ ] Error messages are clear, actionable, and educational\n- [ ] Outputs are properly validated and formatted\n\n### Tool Configuration\n- [ ] All tools implement 'name' and 'annotations' in the decorator\n- [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)\n- [ ] All tools use Pydantic BaseModel for input validation with Field() definitions\n- [ ] All Pydantic Fields have explicit types and descriptions with constraints\n- [ ] All tools have comprehensive docstrings with explicit input/output types\n- [ ] Docstrings include complete schema structure for dict/JSON returns\n- [ ] Pydantic models handle input validation (no manual validation needed)\n\n### Advanced Features (where applicable)\n- [ ] Context injection used for logging, progress, or elicitation\n- [ ] Resources registered for appropriate data endpoints\n- [ ] Lifespan management implemented for persistent connections\n- [ ] Structured output types used (TypedDict, Pydantic models)\n- [ ] Appropriate transport configured (stdio, HTTP, SSE)\n\n### Code Quality\n- [ ] File includes proper imports including Pydantic imports\n- [ ] Pagination is properly implemented where applicable\n- [ ] Large responses check CHARACTER_LIMIT and truncate with clear messages\n- [ ] Filtering options are provided for potentially large result sets\n- [ ] All async functions are properly defined with `async def`\n- [ ] HTTP client usage follows async patterns with proper context managers\n- [ ] Type hints are used throughout the code\n- [ ] Constants are defined at module level in UPPER_CASE\n\n### Testing\n- [ ] Server runs successfully: `python your_server.py --help`\n- [ ] All imports resolve correctly\n- [ ] Sample tool calls work as expected\n- [ ] Error scenarios handled gracefully"
  },
  {
    "path": "mcp-builder/scripts/connections.py",
    "content": "\"\"\"Lightweight connection handling for MCP servers.\"\"\"\n\nfrom abc import ABC, abstractmethod\nfrom contextlib import AsyncExitStack\nfrom typing import Any\n\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.sse import sse_client\nfrom mcp.client.stdio import stdio_client\nfrom mcp.client.streamable_http import streamablehttp_client\n\n\nclass MCPConnection(ABC):\n    \"\"\"Base class for MCP server connections.\"\"\"\n\n    def __init__(self):\n        self.session = None\n        self._stack = None\n\n    @abstractmethod\n    def _create_context(self):\n        \"\"\"Create the connection context based on connection type.\"\"\"\n\n    async def __aenter__(self):\n        \"\"\"Initialize MCP server connection.\"\"\"\n        self._stack = AsyncExitStack()\n        await self._stack.__aenter__()\n\n        try:\n            ctx = self._create_context()\n            result = await self._stack.enter_async_context(ctx)\n\n            if len(result) == 2:\n                read, write = result\n            elif len(result) == 3:\n                read, write, _ = result\n            else:\n                raise ValueError(f\"Unexpected context result: {result}\")\n\n            session_ctx = ClientSession(read, write)\n            self.session = await self._stack.enter_async_context(session_ctx)\n            await self.session.initialize()\n            return self\n        except BaseException:\n            await self._stack.__aexit__(None, None, None)\n            raise\n\n    async def __aexit__(self, exc_type, exc_val, exc_tb):\n        \"\"\"Clean up MCP server connection resources.\"\"\"\n        if self._stack:\n            await self._stack.__aexit__(exc_type, exc_val, exc_tb)\n        self.session = None\n        self._stack = None\n\n    async def list_tools(self) -> list[dict[str, Any]]:\n        \"\"\"Retrieve available tools from the MCP server.\"\"\"\n        response = await self.session.list_tools()\n        return [\n            {\n                \"name\": tool.name,\n                \"description\": tool.description,\n                \"input_schema\": tool.inputSchema,\n            }\n            for tool in response.tools\n        ]\n\n    async def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any:\n        \"\"\"Call a tool on the MCP server with provided arguments.\"\"\"\n        result = await self.session.call_tool(tool_name, arguments=arguments)\n        return result.content\n\n\nclass MCPConnectionStdio(MCPConnection):\n    \"\"\"MCP connection using standard input/output.\"\"\"\n\n    def __init__(self, command: str, args: list[str] = None, env: dict[str, str] = None):\n        super().__init__()\n        self.command = command\n        self.args = args or []\n        self.env = env\n\n    def _create_context(self):\n        return stdio_client(\n            StdioServerParameters(command=self.command, args=self.args, env=self.env)\n        )\n\n\nclass MCPConnectionSSE(MCPConnection):\n    \"\"\"MCP connection using Server-Sent Events.\"\"\"\n\n    def __init__(self, url: str, headers: dict[str, str] = None):\n        super().__init__()\n        self.url = url\n        self.headers = headers or {}\n\n    def _create_context(self):\n        return sse_client(url=self.url, headers=self.headers)\n\n\nclass MCPConnectionHTTP(MCPConnection):\n    \"\"\"MCP connection using Streamable HTTP.\"\"\"\n\n    def __init__(self, url: str, headers: dict[str, str] = None):\n        super().__init__()\n        self.url = url\n        self.headers = headers or {}\n\n    def _create_context(self):\n        return streamablehttp_client(url=self.url, headers=self.headers)\n\n\ndef create_connection(\n    transport: str,\n    command: str = None,\n    args: list[str] = None,\n    env: dict[str, str] = None,\n    url: str = None,\n    headers: dict[str, str] = None,\n) -> MCPConnection:\n    \"\"\"Factory function to create the appropriate MCP connection.\n\n    Args:\n        transport: Connection type (\"stdio\", \"sse\", or \"http\")\n        command: Command to run (stdio only)\n        args: Command arguments (stdio only)\n        env: Environment variables (stdio only)\n        url: Server URL (sse and http only)\n        headers: HTTP headers (sse and http only)\n\n    Returns:\n        MCPConnection instance\n    \"\"\"\n    transport = transport.lower()\n\n    if transport == \"stdio\":\n        if not command:\n            raise ValueError(\"Command is required for stdio transport\")\n        return MCPConnectionStdio(command=command, args=args, env=env)\n\n    elif transport == \"sse\":\n        if not url:\n            raise ValueError(\"URL is required for sse transport\")\n        return MCPConnectionSSE(url=url, headers=headers)\n\n    elif transport in [\"http\", \"streamable_http\", \"streamable-http\"]:\n        if not url:\n            raise ValueError(\"URL is required for http transport\")\n        return MCPConnectionHTTP(url=url, headers=headers)\n\n    else:\n        raise ValueError(f\"Unsupported transport type: {transport}. Use 'stdio', 'sse', or 'http'\")\n"
  },
  {
    "path": "mcp-builder/scripts/evaluation.py",
    "content": "\"\"\"MCP Server Evaluation Harness\n\nThis script evaluates MCP servers by running test questions against them using Claude.\n\"\"\"\n\nimport argparse\nimport asyncio\nimport json\nimport re\nimport sys\nimport time\nimport traceback\nimport xml.etree.ElementTree as ET\nfrom pathlib import Path\nfrom typing import Any\n\nfrom anthropic import Anthropic\n\nfrom connections import create_connection\n\nEVALUATION_PROMPT = \"\"\"You are an AI assistant with access to tools.\n\nWhen given a task, you MUST:\n1. Use the available tools to complete the task\n2. Provide summary of each step in your approach, wrapped in <summary> tags\n3. Provide feedback on the tools provided, wrapped in <feedback> tags\n4. Provide your final response, wrapped in <response> tags\n\nSummary Requirements:\n- In your <summary> tags, you must explain:\n  - The steps you took to complete the task\n  - Which tools you used, in what order, and why\n  - The inputs you provided to each tool\n  - The outputs you received from each tool\n  - A summary for how you arrived at the response\n\nFeedback Requirements:\n- In your <feedback> tags, provide constructive feedback on the tools:\n  - Comment on tool names: Are they clear and descriptive?\n  - Comment on input parameters: Are they well-documented? Are required vs optional parameters clear?\n  - Comment on descriptions: Do they accurately describe what the tool does?\n  - Comment on any errors encountered during tool usage: Did the tool fail to execute? Did the tool return too many tokens?\n  - Identify specific areas for improvement and explain WHY they would help\n  - Be specific and actionable in your suggestions\n\nResponse Requirements:\n- Your response should be concise and directly address what was asked\n- Always wrap your final response in <response> tags\n- If you cannot solve the task return <response>NOT_FOUND</response>\n- For numeric responses, provide just the number\n- For IDs, provide just the ID\n- For names or text, provide the exact text requested\n- Your response should go last\"\"\"\n\n\ndef parse_evaluation_file(file_path: Path) -> list[dict[str, Any]]:\n    \"\"\"Parse XML evaluation file with qa_pair elements.\"\"\"\n    try:\n        tree = ET.parse(file_path)\n        root = tree.getroot()\n        evaluations = []\n\n        for qa_pair in root.findall(\".//qa_pair\"):\n            question_elem = qa_pair.find(\"question\")\n            answer_elem = qa_pair.find(\"answer\")\n\n            if question_elem is not None and answer_elem is not None:\n                evaluations.append({\n                    \"question\": (question_elem.text or \"\").strip(),\n                    \"answer\": (answer_elem.text or \"\").strip(),\n                })\n\n        return evaluations\n    except Exception as e:\n        print(f\"Error parsing evaluation file {file_path}: {e}\")\n        return []\n\n\ndef extract_xml_content(text: str, tag: str) -> str | None:\n    \"\"\"Extract content from XML tags.\"\"\"\n    pattern = rf\"<{tag}>(.*?)</{tag}>\"\n    matches = re.findall(pattern, text, re.DOTALL)\n    return matches[-1].strip() if matches else None\n\n\nasync def agent_loop(\n    client: Anthropic,\n    model: str,\n    question: str,\n    tools: list[dict[str, Any]],\n    connection: Any,\n) -> tuple[str, dict[str, Any]]:\n    \"\"\"Run the agent loop with MCP tools.\"\"\"\n    messages = [{\"role\": \"user\", \"content\": question}]\n\n    response = await asyncio.to_thread(\n        client.messages.create,\n        model=model,\n        max_tokens=4096,\n        system=EVALUATION_PROMPT,\n        messages=messages,\n        tools=tools,\n    )\n\n    messages.append({\"role\": \"assistant\", \"content\": response.content})\n\n    tool_metrics = {}\n\n    while response.stop_reason == \"tool_use\":\n        tool_use = next(block for block in response.content if block.type == \"tool_use\")\n        tool_name = tool_use.name\n        tool_input = tool_use.input\n\n        tool_start_ts = time.time()\n        try:\n            tool_result = await connection.call_tool(tool_name, tool_input)\n            tool_response = json.dumps(tool_result) if isinstance(tool_result, (dict, list)) else str(tool_result)\n        except Exception as e:\n            tool_response = f\"Error executing tool {tool_name}: {str(e)}\\n\"\n            tool_response += traceback.format_exc()\n        tool_duration = time.time() - tool_start_ts\n\n        if tool_name not in tool_metrics:\n            tool_metrics[tool_name] = {\"count\": 0, \"durations\": []}\n        tool_metrics[tool_name][\"count\"] += 1\n        tool_metrics[tool_name][\"durations\"].append(tool_duration)\n\n        messages.append({\n            \"role\": \"user\",\n            \"content\": [{\n                \"type\": \"tool_result\",\n                \"tool_use_id\": tool_use.id,\n                \"content\": tool_response,\n            }]\n        })\n\n        response = await asyncio.to_thread(\n            client.messages.create,\n            model=model,\n            max_tokens=4096,\n            system=EVALUATION_PROMPT,\n            messages=messages,\n            tools=tools,\n        )\n        messages.append({\"role\": \"assistant\", \"content\": response.content})\n\n    response_text = next(\n        (block.text for block in response.content if hasattr(block, \"text\")),\n        None,\n    )\n    return response_text, tool_metrics\n\n\nasync def evaluate_single_task(\n    client: Anthropic,\n    model: str,\n    qa_pair: dict[str, Any],\n    tools: list[dict[str, Any]],\n    connection: Any,\n    task_index: int,\n) -> dict[str, Any]:\n    \"\"\"Evaluate a single QA pair with the given tools.\"\"\"\n    start_time = time.time()\n\n    print(f\"Task {task_index + 1}: Running task with question: {qa_pair['question']}\")\n    response, tool_metrics = await agent_loop(client, model, qa_pair[\"question\"], tools, connection)\n\n    response_value = extract_xml_content(response, \"response\")\n    summary = extract_xml_content(response, \"summary\")\n    feedback = extract_xml_content(response, \"feedback\")\n\n    duration_seconds = time.time() - start_time\n\n    return {\n        \"question\": qa_pair[\"question\"],\n        \"expected\": qa_pair[\"answer\"],\n        \"actual\": response_value,\n        \"score\": int(response_value == qa_pair[\"answer\"]) if response_value else 0,\n        \"total_duration\": duration_seconds,\n        \"tool_calls\": tool_metrics,\n        \"num_tool_calls\": sum(len(metrics[\"durations\"]) for metrics in tool_metrics.values()),\n        \"summary\": summary,\n        \"feedback\": feedback,\n    }\n\n\nREPORT_HEADER = \"\"\"\n# Evaluation Report\n\n## Summary\n\n- **Accuracy**: {correct}/{total} ({accuracy:.1f}%)\n- **Average Task Duration**: {average_duration_s:.2f}s\n- **Average Tool Calls per Task**: {average_tool_calls:.2f}\n- **Total Tool Calls**: {total_tool_calls}\n\n---\n\"\"\"\n\nTASK_TEMPLATE = \"\"\"\n### Task {task_num}\n\n**Question**: {question}\n**Ground Truth Answer**: `{expected_answer}`\n**Actual Answer**: `{actual_answer}`\n**Correct**: {correct_indicator}\n**Duration**: {total_duration:.2f}s\n**Tool Calls**: {tool_calls}\n\n**Summary**\n{summary}\n\n**Feedback**\n{feedback}\n\n---\n\"\"\"\n\n\nasync def run_evaluation(\n    eval_path: Path,\n    connection: Any,\n    model: str = \"claude-3-7-sonnet-20250219\",\n) -> str:\n    \"\"\"Run evaluation with MCP server tools.\"\"\"\n    print(\"🚀 Starting Evaluation\")\n\n    client = Anthropic()\n\n    tools = await connection.list_tools()\n    print(f\"📋 Loaded {len(tools)} tools from MCP server\")\n\n    qa_pairs = parse_evaluation_file(eval_path)\n    print(f\"📋 Loaded {len(qa_pairs)} evaluation tasks\")\n\n    results = []\n    for i, qa_pair in enumerate(qa_pairs):\n        print(f\"Processing task {i + 1}/{len(qa_pairs)}\")\n        result = await evaluate_single_task(client, model, qa_pair, tools, connection, i)\n        results.append(result)\n\n    correct = sum(r[\"score\"] for r in results)\n    accuracy = (correct / len(results)) * 100 if results else 0\n    average_duration_s = sum(r[\"total_duration\"] for r in results) / len(results) if results else 0\n    average_tool_calls = sum(r[\"num_tool_calls\"] for r in results) / len(results) if results else 0\n    total_tool_calls = sum(r[\"num_tool_calls\"] for r in results)\n\n    report = REPORT_HEADER.format(\n        correct=correct,\n        total=len(results),\n        accuracy=accuracy,\n        average_duration_s=average_duration_s,\n        average_tool_calls=average_tool_calls,\n        total_tool_calls=total_tool_calls,\n    )\n\n    report += \"\".join([\n        TASK_TEMPLATE.format(\n            task_num=i + 1,\n            question=qa_pair[\"question\"],\n            expected_answer=qa_pair[\"answer\"],\n            actual_answer=result[\"actual\"] or \"N/A\",\n            correct_indicator=\"✅\" if result[\"score\"] else \"❌\",\n            total_duration=result[\"total_duration\"],\n            tool_calls=json.dumps(result[\"tool_calls\"], indent=2),\n            summary=result[\"summary\"] or \"N/A\",\n            feedback=result[\"feedback\"] or \"N/A\",\n        )\n        for i, (qa_pair, result) in enumerate(zip(qa_pairs, results))\n    ])\n\n    return report\n\n\ndef parse_headers(header_list: list[str]) -> dict[str, str]:\n    \"\"\"Parse header strings in format 'Key: Value' into a dictionary.\"\"\"\n    headers = {}\n    if not header_list:\n        return headers\n\n    for header in header_list:\n        if \":\" in header:\n            key, value = header.split(\":\", 1)\n            headers[key.strip()] = value.strip()\n        else:\n            print(f\"Warning: Ignoring malformed header: {header}\")\n    return headers\n\n\ndef parse_env_vars(env_list: list[str]) -> dict[str, str]:\n    \"\"\"Parse environment variable strings in format 'KEY=VALUE' into a dictionary.\"\"\"\n    env = {}\n    if not env_list:\n        return env\n\n    for env_var in env_list:\n        if \"=\" in env_var:\n            key, value = env_var.split(\"=\", 1)\n            env[key.strip()] = value.strip()\n        else:\n            print(f\"Warning: Ignoring malformed environment variable: {env_var}\")\n    return env\n\n\nasync def main():\n    parser = argparse.ArgumentParser(\n        description=\"Evaluate MCP servers using test questions\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  # Evaluate a local stdio MCP server\n  python evaluation.py -t stdio -c python -a my_server.py eval.xml\n\n  # Evaluate an SSE MCP server\n  python evaluation.py -t sse -u https://example.com/mcp -H \"Authorization: Bearer token\" eval.xml\n\n  # Evaluate an HTTP MCP server with custom model\n  python evaluation.py -t http -u https://example.com/mcp -m claude-3-5-sonnet-20241022 eval.xml\n        \"\"\",\n    )\n\n    parser.add_argument(\"eval_file\", type=Path, help=\"Path to evaluation XML file\")\n    parser.add_argument(\"-t\", \"--transport\", choices=[\"stdio\", \"sse\", \"http\"], default=\"stdio\", help=\"Transport type (default: stdio)\")\n    parser.add_argument(\"-m\", \"--model\", default=\"claude-3-7-sonnet-20250219\", help=\"Claude model to use (default: claude-3-7-sonnet-20250219)\")\n\n    stdio_group = parser.add_argument_group(\"stdio options\")\n    stdio_group.add_argument(\"-c\", \"--command\", help=\"Command to run MCP server (stdio only)\")\n    stdio_group.add_argument(\"-a\", \"--args\", nargs=\"+\", help=\"Arguments for the command (stdio only)\")\n    stdio_group.add_argument(\"-e\", \"--env\", nargs=\"+\", help=\"Environment variables in KEY=VALUE format (stdio only)\")\n\n    remote_group = parser.add_argument_group(\"sse/http options\")\n    remote_group.add_argument(\"-u\", \"--url\", help=\"MCP server URL (sse/http only)\")\n    remote_group.add_argument(\"-H\", \"--header\", nargs=\"+\", dest=\"headers\", help=\"HTTP headers in 'Key: Value' format (sse/http only)\")\n\n    parser.add_argument(\"-o\", \"--output\", type=Path, help=\"Output file for evaluation report (default: stdout)\")\n\n    args = parser.parse_args()\n\n    if not args.eval_file.exists():\n        print(f\"Error: Evaluation file not found: {args.eval_file}\")\n        sys.exit(1)\n\n    headers = parse_headers(args.headers) if args.headers else None\n    env_vars = parse_env_vars(args.env) if args.env else None\n\n    try:\n        connection = create_connection(\n            transport=args.transport,\n            command=args.command,\n            args=args.args,\n            env=env_vars,\n            url=args.url,\n            headers=headers,\n        )\n    except ValueError as e:\n        print(f\"Error: {e}\")\n        sys.exit(1)\n\n    print(f\"🔗 Connecting to MCP server via {args.transport}...\")\n\n    async with connection:\n        print(\"✅ Connected successfully\")\n        report = await run_evaluation(args.eval_file, connection, args.model)\n\n        if args.output:\n            args.output.write_text(report)\n            print(f\"\\n✅ Report saved to {args.output}\")\n        else:\n            print(\"\\n\" + report)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "mcp-builder/scripts/example_evaluation.xml",
    "content": "<evaluation>\n   <qa_pair>\n      <question>Calculate the compound interest on $10,000 invested at 5% annual interest rate, compounded monthly for 3 years. What is the final amount in dollars (rounded to 2 decimal places)?</question>\n      <answer>11614.72</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>A projectile is launched at a 45-degree angle with an initial velocity of 50 m/s. Calculate the total distance (in meters) it has traveled from the launch point after 2 seconds, assuming g=9.8 m/s². Round to 2 decimal places.</question>\n      <answer>87.25</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>A sphere has a volume of 500 cubic meters. Calculate its surface area in square meters. Round to 2 decimal places.</question>\n      <answer>304.65</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Calculate the population standard deviation of this dataset: [12, 15, 18, 22, 25, 30, 35]. Round to 2 decimal places.</question>\n      <answer>7.61</answer>\n   </qa_pair>\n   <qa_pair>\n      <question>Calculate the pH of a solution with a hydrogen ion concentration of 3.5 × 10^-5 M. Round to 2 decimal places.</question>\n      <answer>4.46</answer>\n   </qa_pair>\n</evaluation>\n"
  },
  {
    "path": "mcp-builder/scripts/requirements.txt",
    "content": "anthropic>=0.39.0\nmcp>=1.1.0\n"
  },
  {
    "path": "meeting-insights-analyzer/SKILL.md",
    "content": "---\nname: meeting-insights-analyzer\ndescription: Analyzes meeting transcripts and recordings to uncover behavioral patterns, communication insights, and actionable feedback. Identifies when you avoid conflict, use filler words, dominate conversations, or miss opportunities to listen. Perfect for professionals seeking to improve their communication and leadership skills.\n---\n\n# Meeting Insights Analyzer\n\nThis skill transforms your meeting transcripts into actionable insights about your communication patterns, helping you become a more effective communicator and leader.\n\n## When to Use This Skill\n\n- Analyzing your communication patterns across multiple meetings\n- Getting feedback on your leadership and facilitation style\n- Identifying when you avoid difficult conversations\n- Understanding your speaking habits and filler words\n- Tracking improvement in communication skills over time\n- Preparing for performance reviews with concrete examples\n- Coaching team members on their communication style\n\n## What This Skill Does\n\n1. **Pattern Recognition**: Identifies recurring behaviors across meetings like:\n   - Conflict avoidance or indirect communication\n   - Speaking ratios and turn-taking\n   - Question-asking vs. statement-making patterns\n   - Active listening indicators\n   - Decision-making approaches\n\n2. **Communication Analysis**: Evaluates communication effectiveness:\n   - Clarity and directness\n   - Use of filler words and hedging language\n   - Tone and sentiment patterns\n   - Meeting control and facilitation\n\n3. **Actionable Feedback**: Provides specific, timestamped examples with:\n   - What happened\n   - Why it matters\n   - How to improve\n\n4. **Trend Tracking**: Compares patterns over time when analyzing multiple meetings\n\n## How to Use\n\n### Basic Setup\n\n1. Download your meeting transcripts to a folder (e.g., `~/meetings/`)\n2. Navigate to that folder in Claude Code\n3. Ask for the analysis you want\n\n### Quick Start Examples\n\n```\nAnalyze all meetings in this folder and tell me when I avoided conflict.\n```\n\n```\nLook at my meetings from the past month and identify my communication patterns.\n```\n\n```\nCompare my facilitation style between these two meeting folders.\n```\n\n### Advanced Analysis\n\n```\nAnalyze all transcripts in this folder and:\n1. Identify when I interrupted others\n2. Calculate my speaking ratio\n3. Find moments I avoided giving direct feedback\n4. Track my use of filler words\n5. Show examples of good active listening\n```\n\n## Instructions\n\nWhen a user requests meeting analysis:\n\n1. **Discover Available Data**\n   - Scan the folder for transcript files (.txt, .md, .vtt, .srt, .docx)\n   - Check if files contain speaker labels and timestamps\n   - Confirm the date range of meetings\n   - Identify the user's name/identifier in transcripts\n\n2. **Clarify Analysis Goals**\n   \n   If not specified, ask what they want to learn:\n   - Specific behaviors (conflict avoidance, interruptions, filler words)\n   - Communication effectiveness (clarity, directness, listening)\n   - Meeting facilitation skills\n   - Speaking patterns and ratios\n   - Growth areas for improvement\n   \n3. **Analyze Patterns**\n\n   For each requested insight:\n   \n   **Conflict Avoidance**:\n   - Look for hedging language (\"maybe\", \"kind of\", \"I think\")\n   - Indirect phrasing instead of direct requests\n   - Changing subject when tension arises\n   - Agreeing without commitment (\"yeah, but...\")\n   - Not addressing obvious problems\n   \n   **Speaking Ratios**:\n   - Calculate percentage of meeting spent speaking\n   - Count interruptions (by and of the user)\n   - Measure average speaking turn length\n   - Track question vs. statement ratios\n   \n   **Filler Words**:\n   - Count \"um\", \"uh\", \"like\", \"you know\", \"actually\", etc.\n   - Note frequency per minute or per speaking turn\n   - Identify situations where they increase (nervous, uncertain)\n   \n   **Active Listening**:\n   - Questions that reference others' previous points\n   - Paraphrasing or summarizing others' ideas\n   - Building on others' contributions\n   - Asking clarifying questions\n   \n   **Leadership & Facilitation**:\n   - Decision-making approach (directive vs. collaborative)\n   - How disagreements are handled\n   - Inclusion of quieter participants\n   - Time management and agenda control\n   - Follow-up and action item clarity\n\n4. **Provide Specific Examples**\n\n   For each pattern found, include:\n   \n   ```markdown\n   ### [Pattern Name]\n   \n   **Finding**: [One-sentence summary of the pattern]\n   \n   **Frequency**: [X times across Y meetings]\n   \n   **Examples**:\n   \n   1. **[Meeting Name/Date]** - [Timestamp]\n      \n      **What Happened**:\n      > [Actual quote from transcript]\n      \n      **Why This Matters**:\n      [Explanation of the impact or missed opportunity]\n      \n      **Better Approach**:\n      [Specific alternative phrasing or behavior]\n   \n   [Repeat for 2-3 strongest examples]\n   ```\n\n5. **Synthesize Insights**\n\n   After analyzing all patterns, provide:\n   \n   ```markdown\n   # Meeting Insights Summary\n   \n   **Analysis Period**: [Date range]\n   **Meetings Analyzed**: [X meetings]\n   **Total Duration**: [X hours]\n   \n   ## Key Patterns Identified\n   \n   ### 1. [Primary Pattern]\n   - **Observed**: [What you saw]\n   - **Impact**: [Why it matters]\n   - **Recommendation**: [How to improve]\n   \n   ### 2. [Second Pattern]\n   [Same structure]\n   \n   ## Communication Strengths\n   \n   1. [Strength 1 with example]\n   2. [Strength 2 with example]\n   3. [Strength 3 with example]\n   \n   ## Growth Opportunities\n   \n   1. **[Area 1]**: [Specific, actionable advice]\n   2. **[Area 2]**: [Specific, actionable advice]\n   3. **[Area 3]**: [Specific, actionable advice]\n   \n   ## Speaking Statistics\n   \n   - Average speaking time: [X% of meeting]\n   - Questions asked: [X per meeting average]\n   - Filler words: [X per minute]\n   - Interruptions: [X given / Y received per meeting]\n   \n   ## Next Steps\n   \n   [3-5 concrete actions to improve communication]\n   ```\n\n6. **Offer Follow-Up Options**\n   - Track these same metrics in future meetings\n   - Deep dive into specific meetings or patterns\n   - Compare to industry benchmarks\n   - Create a personal communication development plan\n   - Generate a summary for performance reviews\n\n## Examples\n\n### Example 1: Conflict Avoidance Analysis (Inspired by Dan Shipper)\n\n**User**: \"I download all of my meeting recordings and put them in a folder. Tell me all the times I've subtly avoided conflict.\"\n\n**Output**: \n```markdown\n# Conflict Avoidance Patterns\n\nFound 23 instances across 15 meetings where you used indirect \ncommunication or avoided addressing tensions directly.\n\n## Pattern: Hedging on Critical Feedback\n\n**Frequency**: 8 times across 7 meetings\n\n**Example 1: 1:1 with Sarah** - 00:14:32\n\n**What Happened**:\n> \"So, I was thinking... maybe we could, like, potentially \n> consider looking at the timeline again? I mean, if you \n> think that makes sense. But whatever you think is best!\"\n\n**Why This Matters**:\nYou needed to address that Sarah's project was behind schedule, \nbut the hedging language (\"maybe\", \"potentially\", \"if you think\") \nand the deflection at the end (\"whatever you think\") made it easy \nfor her to miss the urgency.\n\n**Better Approach**:\n\"Sarah, the project is two weeks behind schedule. We need to \ndiscuss what's blocking progress and create a new timeline \ntoday.\"\n\n[Additional examples...]\n\n## Recommendations\n\n1. **Name the issue directly** in the first sentence\n2. **Remove hedging words** like \"maybe,\" \"kind of,\" \"sort of\"\n3. **Ask specific questions** instead of hinting\n4. **Schedule difficult conversations** instead of raising them casually\n```\n\n### Example 2: Leadership Facilitation\n\n**User**: \"Analyze my team meetings and tell me about my facilitation style.\"\n\n**Output**: Provides insights on:\n- How much you speak vs. team members (60% vs. 40%)\n- Whether you ask questions or make statements (3:1 ratio)\n- How you handle disagreements (tendency to resolve too quickly)\n- Who speaks least and whether you draw them in\n- Examples of good and missed facilitation moments\n\n### Example 3: Personal Development Tracking\n\n**User**: \"Compare my meetings from Q1 vs. Q2 to see if I've improved my listening skills.\"\n\n**Output**: Creates a comparative analysis showing:\n- Decrease in interruptions (8 per meeting → 3 per meeting)\n- Increase in clarifying questions (2 → 7 per meeting)\n- Improvement in building on others' ideas\n- Specific examples showing the difference\n- Remaining areas for growth\n\n## Setup Tips\n\n### Getting Meeting Transcripts\n\n**From Granola** (free with Lenny's newsletter subscription):\n- Granola auto-transcribes your meetings\n- Export transcripts to a folder: [Instructions on how]\n- Point Claude Code to that folder\n\n**From Zoom**:\n- Enable cloud recording with transcription\n- Download VTT or SRT files after meetings\n- Store in a dedicated folder\n\n**From Google Meet**:\n- Use Google Docs auto-transcription\n- Save transcript docs to a folder\n- Download as .txt files or give Claude Code access\n\n**From Fireflies.ai, Otter.ai, etc.**:\n- Export transcripts in bulk\n- Store in a local folder\n- Run analysis on the folder\n\n### Best Practices\n\n1. **Consistent naming**: Use `YYYY-MM-DD - Meeting Name.txt` format\n2. **Regular analysis**: Review monthly or quarterly for trends\n3. **Specific queries**: Ask about one behavior at a time for depth\n4. **Privacy**: Keep sensitive meeting data local\n5. **Action-oriented**: Focus on one improvement area at a time\n\n## Common Analysis Requests\n\n- \"When do I avoid difficult conversations?\"\n- \"How often do I interrupt others?\"\n- \"What's my speaking vs. listening ratio?\"\n- \"Do I ask good questions?\"\n- \"How do I handle disagreement?\"\n- \"Am I inclusive of all voices?\"\n- \"Do I use too many filler words?\"\n- \"How clear are my action items?\"\n- \"Do I stay on agenda or get sidetracked?\"\n- \"How has my communication changed over time?\"\n\n## Related Use Cases\n\n- Creating a personal development plan from insights\n- Preparing performance review materials with examples\n- Coaching direct reports on their communication\n- Analyzing customer calls for sales or support patterns\n- Studying negotiation tactics and outcomes\n\n"
  },
  {
    "path": "raffle-winner-picker/SKILL.md",
    "content": "---\nname: raffle-winner-picker\ndescription: Picks random winners from lists, spreadsheets, or Google Sheets for giveaways, raffles, and contests. Ensures fair, unbiased selection with transparency.\n---\n\n# Raffle Winner Picker\n\nThis skill randomly selects winners from lists, spreadsheets, or Google Sheets for giveaways and contests.\n\n## When to Use This Skill\n\n- Running social media giveaways\n- Picking raffle winners at events\n- Randomly selecting participants for surveys or tests\n- Choosing winners from contest submissions\n- Fair distribution of limited spots or resources\n- Random team assignments\n\n## What This Skill Does\n\n1. **Random Selection**: Uses cryptographically random selection\n2. **Multiple Sources**: Works with CSV, Excel, Google Sheets, or plain lists\n3. **Multiple Winners**: Can pick one or multiple winners\n4. **Duplicate Prevention**: Ensures the same person can't win twice\n5. **Transparent Results**: Shows the selection process clearly\n6. **Winner Details**: Displays all relevant information about winners\n\n## How to Use\n\n### From Google Sheets\n\n```\nPick a random row from this Google Sheet to select a winner \nfor a giveaway: [Sheet URL]\n```\n\n### From Local File\n\n```\nPick 3 random winners from entries.csv\n```\n\n### From List\n\n```\nPick a random winner from this list:\n- Alice (alice@email.com)\n- Bob (bob@email.com)\n- Carol (carol@email.com)\n...\n```\n\n### Multiple Winners\n\n```\nPick 5 random winners from contest-entries.xlsx, \nmake sure no duplicates\n```\n\n## Example\n\n**User**: \"Pick a random row from this Google Sheet to select a winner for a giveaway.\"\n\n**Output**:\n```\nAccessing Google Sheet...\nTotal entries found: 247\n\nRandomly selecting winner...\n\n🎉 WINNER SELECTED! 🎉\n\nRow #142\nName: Sarah Johnson\nEmail: sarah.j@email.com\nEntry Date: March 10, 2024\nComment: \"Love your newsletter!\"\n\nSelection method: Cryptographically random\nTimestamp: 2024-03-15 14:32:18 UTC\n\nWould you like to:\n- Pick another winner (excluding Sarah)?\n- Export winner details?\n- Pick runner-ups?\n```\n\n**Inspired by:** Lenny's use case - picking a Sora 2 giveaway winner from his subscriber Slack community\n\n## Features\n\n### Fair Selection\n- Uses secure random number generation\n- No bias or patterns\n- Transparent process\n- Repeatable with seed (for verification)\n\n### Exclusions\n```\nPick a random winner excluding previous winners: \nAlice, Bob, Carol\n```\n\n### Weighted Selection\n```\nPick a winner with weighted probability based on \nthe \"entries\" column (1 entry = 1 ticket)\n```\n\n### Runner-ups\n```\nPick 1 winner and 3 runner-ups from the list\n```\n\n## Example Workflows\n\n### Social Media Giveaway\n1. Export entries from Google Form to Sheets\n2. \"Pick a random winner from [Sheet URL]\"\n3. Verify winner details\n4. Announce publicly with timestamp\n\n### Event Raffle\n1. Create CSV of attendee names and emails\n2. \"Pick 10 random winners from attendees.csv\"\n3. Export winner list\n4. Email winners directly\n\n### Team Assignment\n1. Have list of participants\n2. \"Randomly split this list into 4 equal teams\"\n3. Review assignments\n4. Share team rosters\n\n## Tips\n\n- **Document the process**: Save the timestamp and method\n- **Public announcement**: Share selection details for transparency\n- **Check eligibility**: Verify winner meets contest rules\n- **Have backups**: Pick runner-ups in case winner is ineligible\n- **Export results**: Save winner list for records\n\n## Privacy & Fairness\n\n✓ Uses cryptographically secure randomness\n✓ No manipulation possible\n✓ Timestamp recorded for verification\n✓ Can provide seed for third-party verification\n✓ Respects data privacy\n\n## Common Use Cases\n\n- Newsletter subscriber giveaways\n- Product launch raffles\n- Conference ticket drawings\n- Beta tester selection\n- Focus group participant selection\n- Random prize distribution at events\n\n"
  },
  {
    "path": "skill-creator/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "skill-creator/SKILL.md",
    "content": "---\nname: skill-creator\ndescription: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Skill Creator\n\nThis skill provides guidance for creating effective skills.\n\n## About Skills\n\nSkills are modular, self-contained packages that extend Claude's capabilities by providing\nspecialized knowledge, workflows, and tools. Think of them as \"onboarding guides\" for specific\ndomains or tasks—they transform Claude from a general-purpose agent into a specialized agent\nequipped with procedural knowledge that no model can fully possess.\n\n### What Skills Provide\n\n1. Specialized workflows - Multi-step procedures for specific domains\n2. Tool integrations - Instructions for working with specific file formats or APIs\n3. Domain expertise - Company-specific knowledge, schemas, business logic\n4. Bundled resources - Scripts, references, and assets for complex and repetitive tasks\n\n### Anatomy of a Skill\n\nEvery skill consists of a required SKILL.md file and optional bundled resources:\n\n```\nskill-name/\n├── SKILL.md (required)\n│   ├── YAML frontmatter metadata (required)\n│   │   ├── name: (required)\n│   │   └── description: (required)\n│   └── Markdown instructions (required)\n└── Bundled Resources (optional)\n    ├── scripts/          - Executable code (Python/Bash/etc.)\n    ├── references/       - Documentation intended to be loaded into context as needed\n    └── assets/           - Files used in output (templates, icons, fonts, etc.)\n```\n\n#### SKILL.md (required)\n\n**Metadata Quality:** The `name` and `description` in YAML frontmatter determine when Claude will use the skill. Be specific about what the skill does and when to use it. Use the third-person (e.g. \"This skill should be used when...\" instead of \"Use this skill when...\").\n\n#### Bundled Resources (optional)\n\n##### Scripts (`scripts/`)\n\nExecutable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten.\n\n- **When to include**: When the same code is being rewritten repeatedly or deterministic reliability is needed\n- **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks\n- **Benefits**: Token efficient, deterministic, may be executed without loading into context\n- **Note**: Scripts may still need to be read by Claude for patching or environment-specific adjustments\n\n##### References (`references/`)\n\nDocumentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking.\n\n- **When to include**: For documentation that Claude should reference while working\n- **Examples**: `references/finance.md` for financial schemas, `references/mnda.md` for company NDA template, `references/policies.md` for company policies, `references/api_docs.md` for API specifications\n- **Use cases**: Database schemas, API documentation, domain knowledge, company policies, detailed workflow guides\n- **Benefits**: Keeps SKILL.md lean, loaded only when Claude determines it's needed\n- **Best practice**: If files are large (>10k words), include grep search patterns in SKILL.md\n- **Avoid duplication**: Information should live in either SKILL.md or references files, not both. Prefer references files for detailed information unless it's truly core to the skill—this keeps SKILL.md lean while making information discoverable without hogging the context window. Keep only essential procedural instructions and workflow guidance in SKILL.md; move detailed reference material, schemas, and examples to references files.\n\n##### Assets (`assets/`)\n\nFiles not intended to be loaded into context, but rather used within the output Claude produces.\n\n- **When to include**: When the skill needs files that will be used in the final output\n- **Examples**: `assets/logo.png` for brand assets, `assets/slides.pptx` for PowerPoint templates, `assets/frontend-template/` for HTML/React boilerplate, `assets/font.ttf` for typography\n- **Use cases**: Templates, images, icons, boilerplate code, fonts, sample documents that get copied or modified\n- **Benefits**: Separates output resources from documentation, enables Claude to use files without loading them into context\n\n### Progressive Disclosure Design Principle\n\nSkills use a three-level loading system to manage context efficiently:\n\n1. **Metadata (name + description)** - Always in context (~100 words)\n2. **SKILL.md body** - When skill triggers (<5k words)\n3. **Bundled resources** - As needed by Claude (Unlimited*)\n\n*Unlimited because scripts can be executed without reading into context window.\n\n## Skill Creation Process\n\nTo create a skill, follow the \"Skill Creation Process\" in order, skipping steps only if there is a clear reason why they are not applicable.\n\n### Step 1: Understanding the Skill with Concrete Examples\n\nSkip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill.\n\nTo create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback.\n\nFor example, when building an image-editor skill, relevant questions include:\n\n- \"What functionality should the image-editor skill support? Editing, rotating, anything else?\"\n- \"Can you give some examples of how this skill would be used?\"\n- \"I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?\"\n- \"What would a user say that should trigger this skill?\"\n\nTo avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness.\n\nConclude this step when there is a clear sense of the functionality the skill should support.\n\n### Step 2: Planning the Reusable Skill Contents\n\nTo turn concrete examples into an effective skill, analyze each example by:\n\n1. Considering how to execute on the example from scratch\n2. Identifying what scripts, references, and assets would be helpful when executing these workflows repeatedly\n\nExample: When building a `pdf-editor` skill to handle queries like \"Help me rotate this PDF,\" the analysis shows:\n\n1. Rotating a PDF requires re-writing the same code each time\n2. A `scripts/rotate_pdf.py` script would be helpful to store in the skill\n\nExample: When designing a `frontend-webapp-builder` skill for queries like \"Build me a todo app\" or \"Build me a dashboard to track my steps,\" the analysis shows:\n\n1. Writing a frontend webapp requires the same boilerplate HTML/React each time\n2. An `assets/hello-world/` template containing the boilerplate HTML/React project files would be helpful to store in the skill\n\nExample: When building a `big-query` skill to handle queries like \"How many users have logged in today?\" the analysis shows:\n\n1. Querying BigQuery requires re-discovering the table schemas and relationships each time\n2. A `references/schema.md` file documenting the table schemas would be helpful to store in the skill\n\nTo establish the skill's contents, analyze each concrete example to create a list of the reusable resources to include: scripts, references, and assets.\n\n### Step 3: Initializing the Skill\n\nAt this point, it is time to actually create the skill.\n\nSkip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step.\n\nWhen creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable.\n\nUsage:\n\n```bash\nscripts/init_skill.py <skill-name> --path <output-directory>\n```\n\nThe script:\n\n- Creates the skill directory at the specified path\n- Generates a SKILL.md template with proper frontmatter and TODO placeholders\n- Creates example resource directories: `scripts/`, `references/`, and `assets/`\n- Adds example files in each directory that can be customized or deleted\n\nAfter initialization, customize or remove the generated SKILL.md and example files as needed.\n\n### Step 4: Edit the Skill\n\nWhen editing the (newly-generated or existing) skill, remember that the skill is being created for another instance of Claude to use. Focus on including information that would be beneficial and non-obvious to Claude. Consider what procedural knowledge, domain-specific details, or reusable assets would help another Claude instance execute these tasks more effectively.\n\n#### Start with Reusable Skill Contents\n\nTo begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Note that this step may require user input. For example, when implementing a `brand-guidelines` skill, the user may need to provide brand assets or templates to store in `assets/`, or documentation to store in `references/`.\n\nAlso, delete any example files and directories not needed for the skill. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.\n\n#### Update SKILL.md\n\n**Writing Style:** Write the entire skill using **imperative/infinitive form** (verb-first instructions), not second person. Use objective, instructional language (e.g., \"To accomplish X, do Y\" rather than \"You should do X\" or \"If you need to do X\"). This maintains consistency and clarity for AI consumption.\n\nTo complete SKILL.md, answer the following questions:\n\n1. What is the purpose of the skill, in a few sentences?\n2. When should the skill be used?\n3. In practice, how should Claude use the skill? All reusable skill contents developed above should be referenced so that Claude knows how to use them.\n\n### Step 5: Packaging a Skill\n\nOnce the skill is ready, it should be packaged into a distributable zip file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:\n\n```bash\nscripts/package_skill.py <path/to/skill-folder>\n```\n\nOptional output directory specification:\n\n```bash\nscripts/package_skill.py <path/to/skill-folder> ./dist\n```\n\nThe packaging script will:\n\n1. **Validate** the skill automatically, checking:\n   - YAML frontmatter format and required fields\n   - Skill naming conventions and directory structure\n   - Description completeness and quality\n   - File organization and resource references\n\n2. **Package** the skill if validation passes, creating a zip file named after the skill (e.g., `my-skill.zip`) that includes all files and maintains the proper directory structure for distribution.\n\nIf validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again.\n\n### Step 6: Iterate\n\nAfter testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.\n\n**Iteration workflow:**\n1. Use the skill on real tasks\n2. Notice struggles or inefficiencies\n3. Identify how SKILL.md or bundled resources should be updated\n4. Implement changes and test again\n"
  },
  {
    "path": "skill-creator/scripts/init_skill.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nSkill Initializer - Creates a new skill from template\n\nUsage:\n    init_skill.py <skill-name> --path <path>\n\nExamples:\n    init_skill.py my-new-skill --path skills/public\n    init_skill.py my-api-helper --path skills/private\n    init_skill.py custom-skill --path /custom/location\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\n\nSKILL_TEMPLATE = \"\"\"---\nname: {skill_name}\ndescription: [TODO: Complete and informative explanation of what the skill does and when to use it. Include WHEN to use this skill - specific scenarios, file types, or tasks that trigger it.]\n---\n\n# {skill_title}\n\n## Overview\n\n[TODO: 1-2 sentences explaining what this skill enables]\n\n## Structuring This Skill\n\n[TODO: Choose the structure that best fits this skill's purpose. Common patterns:\n\n**1. Workflow-Based** (best for sequential processes)\n- Works well when there are clear step-by-step procedures\n- Example: DOCX skill with \"Workflow Decision Tree\" → \"Reading\" → \"Creating\" → \"Editing\"\n- Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2...\n\n**2. Task-Based** (best for tool collections)\n- Works well when the skill offers different operations/capabilities\n- Example: PDF skill with \"Quick Start\" → \"Merge PDFs\" → \"Split PDFs\" → \"Extract Text\"\n- Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2...\n\n**3. Reference/Guidelines** (best for standards or specifications)\n- Works well for brand guidelines, coding standards, or requirements\n- Example: Brand styling with \"Brand Guidelines\" → \"Colors\" → \"Typography\" → \"Features\"\n- Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage...\n\n**4. Capabilities-Based** (best for integrated systems)\n- Works well when the skill provides multiple interrelated features\n- Example: Product Management with \"Core Capabilities\" → numbered capability list\n- Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature...\n\nPatterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations).\n\nDelete this entire \"Structuring This Skill\" section when done - it's just guidance.]\n\n## [TODO: Replace with the first main section based on chosen structure]\n\n[TODO: Add content here. See examples in existing skills:\n- Code samples for technical skills\n- Decision trees for complex workflows\n- Concrete examples with realistic user requests\n- References to scripts/templates/references as needed]\n\n## Resources\n\nThis skill includes example resource directories that demonstrate how to organize different types of bundled resources:\n\n### scripts/\nExecutable code (Python/Bash/etc.) that can be run directly to perform specific operations.\n\n**Examples from other skills:**\n- PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation\n- DOCX skill: `document.py`, `utilities.py` - Python modules for document processing\n\n**Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations.\n\n**Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments.\n\n### references/\nDocumentation and reference material intended to be loaded into context to inform Claude's process and thinking.\n\n**Examples from other skills:**\n- Product management: `communication.md`, `context_building.md` - detailed workflow guides\n- BigQuery: API reference documentation and query examples\n- Finance: Schema documentation, company policies\n\n**Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working.\n\n### assets/\nFiles not intended to be loaded into context, but rather used within the output Claude produces.\n\n**Examples from other skills:**\n- Brand styling: PowerPoint template files (.pptx), logo files\n- Frontend builder: HTML/React boilerplate project directories\n- Typography: Font files (.ttf, .woff2)\n\n**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output.\n\n---\n\n**Any unneeded directories can be deleted.** Not every skill requires all three types of resources.\n\"\"\"\n\nEXAMPLE_SCRIPT = '''#!/usr/bin/env python3\n\"\"\"\nExample helper script for {skill_name}\n\nThis is a placeholder script that can be executed directly.\nReplace with actual implementation or delete if not needed.\n\nExample real scripts from other skills:\n- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields\n- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images\n\"\"\"\n\ndef main():\n    print(\"This is an example script for {skill_name}\")\n    # TODO: Add actual script logic here\n    # This could be data processing, file conversion, API calls, etc.\n\nif __name__ == \"__main__\":\n    main()\n'''\n\nEXAMPLE_REFERENCE = \"\"\"# Reference Documentation for {skill_title}\n\nThis is a placeholder for detailed reference documentation.\nReplace with actual reference content or delete if not needed.\n\nExample real reference docs from other skills:\n- product-management/references/communication.md - Comprehensive guide for status updates\n- product-management/references/context_building.md - Deep-dive on gathering context\n- bigquery/references/ - API references and query examples\n\n## When Reference Docs Are Useful\n\nReference docs are ideal for:\n- Comprehensive API documentation\n- Detailed workflow guides\n- Complex multi-step processes\n- Information too lengthy for main SKILL.md\n- Content that's only needed for specific use cases\n\n## Structure Suggestions\n\n### API Reference Example\n- Overview\n- Authentication\n- Endpoints with examples\n- Error codes\n- Rate limits\n\n### Workflow Guide Example\n- Prerequisites\n- Step-by-step instructions\n- Common patterns\n- Troubleshooting\n- Best practices\n\"\"\"\n\nEXAMPLE_ASSET = \"\"\"# Example Asset File\n\nThis placeholder represents where asset files would be stored.\nReplace with actual asset files (templates, images, fonts, etc.) or delete if not needed.\n\nAsset files are NOT intended to be loaded into context, but rather used within\nthe output Claude produces.\n\nExample asset files from other skills:\n- Brand guidelines: logo.png, slides_template.pptx\n- Frontend builder: hello-world/ directory with HTML/React boilerplate\n- Typography: custom-font.ttf, font-family.woff2\n- Data: sample_data.csv, test_dataset.json\n\n## Common Asset Types\n\n- Templates: .pptx, .docx, boilerplate directories\n- Images: .png, .jpg, .svg, .gif\n- Fonts: .ttf, .otf, .woff, .woff2\n- Boilerplate code: Project directories, starter files\n- Icons: .ico, .svg\n- Data files: .csv, .json, .xml, .yaml\n\nNote: This is a text placeholder. Actual assets can be any file type.\n\"\"\"\n\n\ndef title_case_skill_name(skill_name):\n    \"\"\"Convert hyphenated skill name to Title Case for display.\"\"\"\n    return ' '.join(word.capitalize() for word in skill_name.split('-'))\n\n\ndef init_skill(skill_name, path):\n    \"\"\"\n    Initialize a new skill directory with template SKILL.md.\n\n    Args:\n        skill_name: Name of the skill\n        path: Path where the skill directory should be created\n\n    Returns:\n        Path to created skill directory, or None if error\n    \"\"\"\n    # Determine skill directory path\n    skill_dir = Path(path).resolve() / skill_name\n\n    # Check if directory already exists\n    if skill_dir.exists():\n        print(f\"❌ Error: Skill directory already exists: {skill_dir}\")\n        return None\n\n    # Create skill directory\n    try:\n        skill_dir.mkdir(parents=True, exist_ok=False)\n        print(f\"✅ Created skill directory: {skill_dir}\")\n    except Exception as e:\n        print(f\"❌ Error creating directory: {e}\")\n        return None\n\n    # Create SKILL.md from template\n    skill_title = title_case_skill_name(skill_name)\n    skill_content = SKILL_TEMPLATE.format(\n        skill_name=skill_name,\n        skill_title=skill_title\n    )\n\n    skill_md_path = skill_dir / 'SKILL.md'\n    try:\n        skill_md_path.write_text(skill_content)\n        print(\"✅ Created SKILL.md\")\n    except Exception as e:\n        print(f\"❌ Error creating SKILL.md: {e}\")\n        return None\n\n    # Create resource directories with example files\n    try:\n        # Create scripts/ directory with example script\n        scripts_dir = skill_dir / 'scripts'\n        scripts_dir.mkdir(exist_ok=True)\n        example_script = scripts_dir / 'example.py'\n        example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name))\n        example_script.chmod(0o755)\n        print(\"✅ Created scripts/example.py\")\n\n        # Create references/ directory with example reference doc\n        references_dir = skill_dir / 'references'\n        references_dir.mkdir(exist_ok=True)\n        example_reference = references_dir / 'api_reference.md'\n        example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title))\n        print(\"✅ Created references/api_reference.md\")\n\n        # Create assets/ directory with example asset placeholder\n        assets_dir = skill_dir / 'assets'\n        assets_dir.mkdir(exist_ok=True)\n        example_asset = assets_dir / 'example_asset.txt'\n        example_asset.write_text(EXAMPLE_ASSET)\n        print(\"✅ Created assets/example_asset.txt\")\n    except Exception as e:\n        print(f\"❌ Error creating resource directories: {e}\")\n        return None\n\n    # Print next steps\n    print(f\"\\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}\")\n    print(\"\\nNext steps:\")\n    print(\"1. Edit SKILL.md to complete the TODO items and update the description\")\n    print(\"2. Customize or delete the example files in scripts/, references/, and assets/\")\n    print(\"3. Run the validator when ready to check the skill structure\")\n\n    return skill_dir\n\n\ndef main():\n    if len(sys.argv) < 4 or sys.argv[2] != '--path':\n        print(\"Usage: init_skill.py <skill-name> --path <path>\")\n        print(\"\\nSkill name requirements:\")\n        print(\"  - Hyphen-case identifier (e.g., 'data-analyzer')\")\n        print(\"  - Lowercase letters, digits, and hyphens only\")\n        print(\"  - Max 40 characters\")\n        print(\"  - Must match directory name exactly\")\n        print(\"\\nExamples:\")\n        print(\"  init_skill.py my-new-skill --path skills/public\")\n        print(\"  init_skill.py my-api-helper --path skills/private\")\n        print(\"  init_skill.py custom-skill --path /custom/location\")\n        sys.exit(1)\n\n    skill_name = sys.argv[1]\n    path = sys.argv[3]\n\n    print(f\"🚀 Initializing skill: {skill_name}\")\n    print(f\"   Location: {path}\")\n    print()\n\n    result = init_skill(skill_name, path)\n\n    if result:\n        sys.exit(0)\n    else:\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skill-creator/scripts/package_skill.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nSkill Packager - Creates a distributable zip file of a skill folder\n\nUsage:\n    python utils/package_skill.py <path/to/skill-folder> [output-directory]\n\nExample:\n    python utils/package_skill.py skills/public/my-skill\n    python utils/package_skill.py skills/public/my-skill ./dist\n\"\"\"\n\nimport sys\nimport zipfile\nfrom pathlib import Path\nfrom quick_validate import validate_skill\n\n\ndef package_skill(skill_path, output_dir=None):\n    \"\"\"\n    Package a skill folder into a zip file.\n\n    Args:\n        skill_path: Path to the skill folder\n        output_dir: Optional output directory for the zip file (defaults to current directory)\n\n    Returns:\n        Path to the created zip file, or None if error\n    \"\"\"\n    skill_path = Path(skill_path).resolve()\n\n    # Validate skill folder exists\n    if not skill_path.exists():\n        print(f\"❌ Error: Skill folder not found: {skill_path}\")\n        return None\n\n    if not skill_path.is_dir():\n        print(f\"❌ Error: Path is not a directory: {skill_path}\")\n        return None\n\n    # Validate SKILL.md exists\n    skill_md = skill_path / \"SKILL.md\"\n    if not skill_md.exists():\n        print(f\"❌ Error: SKILL.md not found in {skill_path}\")\n        return None\n\n    # Run validation before packaging\n    print(\"🔍 Validating skill...\")\n    valid, message = validate_skill(skill_path)\n    if not valid:\n        print(f\"❌ Validation failed: {message}\")\n        print(\"   Please fix the validation errors before packaging.\")\n        return None\n    print(f\"✅ {message}\\n\")\n\n    # Determine output location\n    skill_name = skill_path.name\n    if output_dir:\n        output_path = Path(output_dir).resolve()\n        output_path.mkdir(parents=True, exist_ok=True)\n    else:\n        output_path = Path.cwd()\n\n    zip_filename = output_path / f\"{skill_name}.zip\"\n\n    # Create the zip file\n    try:\n        with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:\n            # Walk through the skill directory\n            for file_path in skill_path.rglob('*'):\n                if file_path.is_file():\n                    # Calculate the relative path within the zip\n                    arcname = file_path.relative_to(skill_path.parent)\n                    zipf.write(file_path, arcname)\n                    print(f\"  Added: {arcname}\")\n\n        print(f\"\\n✅ Successfully packaged skill to: {zip_filename}\")\n        return zip_filename\n\n    except Exception as e:\n        print(f\"❌ Error creating zip file: {e}\")\n        return None\n\n\ndef main():\n    if len(sys.argv) < 2:\n        print(\"Usage: python utils/package_skill.py <path/to/skill-folder> [output-directory]\")\n        print(\"\\nExample:\")\n        print(\"  python utils/package_skill.py skills/public/my-skill\")\n        print(\"  python utils/package_skill.py skills/public/my-skill ./dist\")\n        sys.exit(1)\n\n    skill_path = sys.argv[1]\n    output_dir = sys.argv[2] if len(sys.argv) > 2 else None\n\n    print(f\"📦 Packaging skill: {skill_path}\")\n    if output_dir:\n        print(f\"   Output directory: {output_dir}\")\n    print()\n\n    result = package_skill(skill_path, output_dir)\n\n    if result:\n        sys.exit(0)\n    else:\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "skill-creator/scripts/quick_validate.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nQuick validation script for skills - minimal version\n\"\"\"\n\nimport sys\nimport os\nimport re\nfrom pathlib import Path\n\ndef validate_skill(skill_path):\n    \"\"\"Basic validation of a skill\"\"\"\n    skill_path = Path(skill_path)\n    \n    # Check SKILL.md exists\n    skill_md = skill_path / 'SKILL.md'\n    if not skill_md.exists():\n        return False, \"SKILL.md not found\"\n    \n    # Read and validate frontmatter\n    content = skill_md.read_text()\n    if not content.startswith('---'):\n        return False, \"No YAML frontmatter found\"\n    \n    # Extract frontmatter\n    match = re.match(r'^---\\n(.*?)\\n---', content, re.DOTALL)\n    if not match:\n        return False, \"Invalid frontmatter format\"\n    \n    frontmatter = match.group(1)\n    \n    # Check required fields\n    if 'name:' not in frontmatter:\n        return False, \"Missing 'name' in frontmatter\"\n    if 'description:' not in frontmatter:\n        return False, \"Missing 'description' in frontmatter\"\n    \n    # Extract name for validation\n    name_match = re.search(r'name:\\s*(.+)', frontmatter)\n    if name_match:\n        name = name_match.group(1).strip()\n        # Check naming convention (hyphen-case: lowercase with hyphens)\n        if not re.match(r'^[a-z0-9-]+$', name):\n            return False, f\"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)\"\n        if name.startswith('-') or name.endswith('-') or '--' in name:\n            return False, f\"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens\"\n\n    # Extract and validate description\n    desc_match = re.search(r'description:\\s*(.+)', frontmatter)\n    if desc_match:\n        description = desc_match.group(1).strip()\n        # Check for angle brackets\n        if '<' in description or '>' in description:\n            return False, \"Description cannot contain angle brackets (< or >)\"\n\n    return True, \"Skill is valid!\"\n\nif __name__ == \"__main__\":\n    if len(sys.argv) != 2:\n        print(\"Usage: python quick_validate.py <skill_directory>\")\n        sys.exit(1)\n    \n    valid, message = validate_skill(sys.argv[1])\n    print(message)\n    sys.exit(0 if valid else 1)"
  },
  {
    "path": "skill-share/SKILL.md",
    "content": "---\nname: skill-share\ndescription: A skill that creates new Claude skills and automatically shares them on Slack using Rube for seamless team collaboration and skill discovery.\nlicense: Complete terms in LICENSE.txt\n---\n\n## When to use this skill\n\nUse this skill when you need to:\n- **Create new Claude skills** with proper structure and metadata\n- **Generate skill packages** ready for distribution\n- **Automatically share created skills** on Slack channels for team visibility\n- **Validate skill structure** before sharing\n- **Package and distribute** skills to your team\n\nAlso use this skill when:\n- **User says he wants to create/share his skill** \n\nThis skill is ideal for:\n- Creating skills as part of team workflows\n- Building internal tools that need skill creation + team notification\n- Automating the skill development pipeline\n- Collaborative skill creation with team notifications\n\n## Key Features\n\n### 1. Skill Creation\n- Creates properly structured skill directories with SKILL.md\n- Generates standardized scripts/, references/, and assets/ directories\n- Auto-generates YAML frontmatter with required metadata\n- Enforces naming conventions (hyphen-case)\n\n### 2. Skill Validation\n- Validates SKILL.md format and required fields\n- Checks naming conventions\n- Ensures metadata completeness before packaging\n\n### 3. Skill Packaging\n- Creates distributable zip files\n- Includes all skill assets and documentation\n- Runs validation automatically before packaging\n\n### 4. Slack Integration via Rube\n- Automatically sends created skill information to designated Slack channels\n- Shares skill metadata (name, description, link)\n- Posts skill summary for team discovery\n- Provides direct links to skill files\n\n## How It Works\n\n1. **Initialization**: Provide skill name and description\n2. **Creation**: Skill directory is created with proper structure\n3. **Validation**: Skill metadata is validated for correctness\n4. **Packaging**: Skill is packaged into a distributable format\n5. **Slack Notification**: Skill details are posted to your team's Slack channel\n\n## Example Usage\n\n```\nWhen you ask Claude to create a skill called \"pdf-analyzer\":\n1. Creates /skill-pdf-analyzer/ with SKILL.md template\n2. Generates structured directories (scripts/, references/, assets/)\n3. Validates the skill structure\n4. Packages the skill as a zip file\n5. Posts to Slack: \"New Skill Created: pdf-analyzer - Advanced PDF analysis and extraction capabilities\"\n```\n\n## Integration with Rube\n\nThis skill leverages Rube for:\n- **SLACK_SEND_MESSAGE**: Posts skill information to team channels\n- **SLACK_POST_MESSAGE_WITH_BLOCKS**: Shares rich formatted skill metadata\n- **SLACK_FIND_CHANNELS**: Discovers target channels for skill announcements\n\n## Requirements\n\n- Slack workspace connection via Rube\n- Write access to skill creation directory\n- Python 3.7+ for skill creation scripts\n- Target Slack channel for skill notifications\n"
  },
  {
    "path": "slack-gif-creator/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "slack-gif-creator/SKILL.md",
    "content": "---\nname: slack-gif-creator\ndescription: Toolkit for creating animated GIFs optimized for Slack, with validators for size constraints and composable animation primitives. This skill applies when users request animated GIFs or emoji animations for Slack from descriptions like \"make me a GIF for Slack of X doing Y\".\nlicense: Complete terms in LICENSE.txt\n---\n\n# Slack GIF Creator - Flexible Toolkit\n\nA toolkit for creating animated GIFs optimized for Slack. Provides validators for Slack's constraints, composable animation primitives, and optional helper utilities. **Apply these tools however needed to achieve the creative vision.**\n\n## Slack's Requirements\n\nSlack has specific requirements for GIFs based on their use:\n\n**Message GIFs:**\n- Max size: ~2MB\n- Optimal dimensions: 480x480\n- Typical FPS: 15-20\n- Color limit: 128-256\n- Duration: 2-5s\n\n**Emoji GIFs:**\n- Max size: 64KB (strict limit)\n- Optimal dimensions: 128x128\n- Typical FPS: 10-12\n- Color limit: 32-48\n- Duration: 1-2s\n\n**Emoji GIFs are challenging** - the 64KB limit is strict. Strategies that help:\n- Limit to 10-15 frames total\n- Use 32-48 colors maximum\n- Keep designs simple\n- Avoid gradients\n- Validate file size frequently\n\n## Toolkit Structure\n\nThis skill provides three types of tools:\n\n1. **Validators** - Check if a GIF meets Slack's requirements\n2. **Animation Primitives** - Composable building blocks for motion (shake, bounce, move, kaleidoscope)\n3. **Helper Utilities** - Optional functions for common needs (text, colors, effects)\n\n**Complete creative freedom is available in how these tools are applied.**\n\n## Core Validators\n\nTo ensure a GIF meets Slack's constraints, use these validators:\n\n```python\nfrom core.gif_builder import GIFBuilder\n\n# After creating your GIF, check if it meets requirements\nbuilder = GIFBuilder(width=128, height=128, fps=10)\n# ... add your frames however you want ...\n\n# Save and check size\ninfo = builder.save('emoji.gif', num_colors=48, optimize_for_emoji=True)\n\n# The save method automatically warns if file exceeds limits\n# info dict contains: size_kb, size_mb, frame_count, duration_seconds\n```\n\n**File size validator**:\n```python\nfrom core.validators import check_slack_size\n\n# Check if GIF meets size limits\npasses, info = check_slack_size('emoji.gif', is_emoji=True)\n# Returns: (True/False, dict with size details)\n```\n\n**Dimension validator**:\n```python\nfrom core.validators import validate_dimensions\n\n# Check dimensions\npasses, info = validate_dimensions(128, 128, is_emoji=True)\n# Returns: (True/False, dict with dimension details)\n```\n\n**Complete validation**:\n```python\nfrom core.validators import validate_gif, is_slack_ready\n\n# Run all validations\nall_pass, results = validate_gif('emoji.gif', is_emoji=True)\n\n# Or quick check\nif is_slack_ready('emoji.gif', is_emoji=True):\n    print(\"Ready to upload!\")\n```\n\n## Animation Primitives\n\nThese are composable building blocks for motion. Apply these to any object in any combination:\n\n### Shake\n```python\nfrom templates.shake import create_shake_animation\n\n# Shake an emoji\nframes = create_shake_animation(\n    object_type='emoji',\n    object_data={'emoji': '😱', 'size': 80},\n    num_frames=20,\n    shake_intensity=15,\n    direction='both'  # or 'horizontal', 'vertical'\n)\n```\n\n### Bounce\n```python\nfrom templates.bounce import create_bounce_animation\n\n# Bounce a circle\nframes = create_bounce_animation(\n    object_type='circle',\n    object_data={'radius': 40, 'color': (255, 100, 100)},\n    num_frames=30,\n    bounce_height=150\n)\n```\n\n### Spin / Rotate\n```python\nfrom templates.spin import create_spin_animation, create_loading_spinner\n\n# Clockwise spin\nframes = create_spin_animation(\n    object_type='emoji',\n    object_data={'emoji': '🔄', 'size': 100},\n    rotation_type='clockwise',\n    full_rotations=2\n)\n\n# Wobble rotation\nframes = create_spin_animation(rotation_type='wobble', full_rotations=3)\n\n# Loading spinner\nframes = create_loading_spinner(spinner_type='dots')\n```\n\n### Pulse / Heartbeat\n```python\nfrom templates.pulse import create_pulse_animation, create_attention_pulse\n\n# Smooth pulse\nframes = create_pulse_animation(\n    object_data={'emoji': '❤️', 'size': 100},\n    pulse_type='smooth',\n    scale_range=(0.8, 1.2)\n)\n\n# Heartbeat (double-pump)\nframes = create_pulse_animation(pulse_type='heartbeat')\n\n# Attention pulse for emoji GIFs\nframes = create_attention_pulse(emoji='⚠️', num_frames=20)\n```\n\n### Fade\n```python\nfrom templates.fade import create_fade_animation, create_crossfade\n\n# Fade in\nframes = create_fade_animation(fade_type='in')\n\n# Fade out\nframes = create_fade_animation(fade_type='out')\n\n# Crossfade between two emojis\nframes = create_crossfade(\n    object1_data={'emoji': '😊', 'size': 100},\n    object2_data={'emoji': '😂', 'size': 100}\n)\n```\n\n### Zoom\n```python\nfrom templates.zoom import create_zoom_animation, create_explosion_zoom\n\n# Zoom in dramatically\nframes = create_zoom_animation(\n    zoom_type='in',\n    scale_range=(0.1, 2.0),\n    add_motion_blur=True\n)\n\n# Zoom out\nframes = create_zoom_animation(zoom_type='out')\n\n# Explosion zoom\nframes = create_explosion_zoom(emoji='💥')\n```\n\n### Explode / Shatter\n```python\nfrom templates.explode import create_explode_animation, create_particle_burst\n\n# Burst explosion\nframes = create_explode_animation(\n    explode_type='burst',\n    num_pieces=25\n)\n\n# Shatter effect\nframes = create_explode_animation(explode_type='shatter')\n\n# Dissolve into particles\nframes = create_explode_animation(explode_type='dissolve')\n\n# Particle burst\nframes = create_particle_burst(particle_count=30)\n```\n\n### Wiggle / Jiggle\n```python\nfrom templates.wiggle import create_wiggle_animation, create_excited_wiggle\n\n# Jello wobble\nframes = create_wiggle_animation(\n    wiggle_type='jello',\n    intensity=1.0,\n    cycles=2\n)\n\n# Wave motion\nframes = create_wiggle_animation(wiggle_type='wave')\n\n# Excited wiggle for emoji GIFs\nframes = create_excited_wiggle(emoji='🎉')\n```\n\n### Slide\n```python\nfrom templates.slide import create_slide_animation, create_multi_slide\n\n# Slide in from left with overshoot\nframes = create_slide_animation(\n    direction='left',\n    slide_type='in',\n    overshoot=True\n)\n\n# Slide across\nframes = create_slide_animation(direction='left', slide_type='across')\n\n# Multiple objects sliding in sequence\nobjects = [\n    {'data': {'emoji': '🎯', 'size': 60}, 'direction': 'left', 'final_pos': (120, 240)},\n    {'data': {'emoji': '🎪', 'size': 60}, 'direction': 'right', 'final_pos': (240, 240)}\n]\nframes = create_multi_slide(objects, stagger_delay=5)\n```\n\n### Flip\n```python\nfrom templates.flip import create_flip_animation, create_quick_flip\n\n# Horizontal flip between two emojis\nframes = create_flip_animation(\n    object1_data={'emoji': '😊', 'size': 120},\n    object2_data={'emoji': '😂', 'size': 120},\n    flip_axis='horizontal'\n)\n\n# Vertical flip\nframes = create_flip_animation(flip_axis='vertical')\n\n# Quick flip for emoji GIFs\nframes = create_quick_flip('👍', '👎')\n```\n\n### Morph / Transform\n```python\nfrom templates.morph import create_morph_animation, create_reaction_morph\n\n# Crossfade morph\nframes = create_morph_animation(\n    object1_data={'emoji': '😊', 'size': 100},\n    object2_data={'emoji': '😂', 'size': 100},\n    morph_type='crossfade'\n)\n\n# Scale morph (shrink while other grows)\nframes = create_morph_animation(morph_type='scale')\n\n# Spin morph (3D flip-like)\nframes = create_morph_animation(morph_type='spin_morph')\n```\n\n### Move Effect\n```python\nfrom templates.move import create_move_animation\n\n# Linear movement\nframes = create_move_animation(\n    object_type='emoji',\n    object_data={'emoji': '🚀', 'size': 60},\n    start_pos=(50, 240),\n    end_pos=(430, 240),\n    motion_type='linear',\n    easing='ease_out'\n)\n\n# Arc movement (parabolic trajectory)\nframes = create_move_animation(\n    object_type='emoji',\n    object_data={'emoji': '⚽', 'size': 60},\n    start_pos=(50, 350),\n    end_pos=(430, 350),\n    motion_type='arc',\n    motion_params={'arc_height': 150}\n)\n\n# Circular movement\nframes = create_move_animation(\n    object_type='emoji',\n    object_data={'emoji': '🌍', 'size': 50},\n    motion_type='circle',\n    motion_params={\n        'center': (240, 240),\n        'radius': 120,\n        'angle_range': 360  # full circle\n    }\n)\n\n# Wave movement\nframes = create_move_animation(\n    motion_type='wave',\n    motion_params={\n        'wave_amplitude': 50,\n        'wave_frequency': 2\n    }\n)\n\n# Or use low-level easing functions\nfrom core.easing import interpolate, calculate_arc_motion\n\nfor i in range(num_frames):\n    t = i / (num_frames - 1)\n    x = interpolate(start_x, end_x, t, easing='ease_out')\n    # Or: x, y = calculate_arc_motion(start, end, height, t)\n```\n\n### Kaleidoscope Effect\n```python\nfrom templates.kaleidoscope import apply_kaleidoscope, create_kaleidoscope_animation\n\n# Apply to a single frame\nkaleido_frame = apply_kaleidoscope(frame, segments=8)\n\n# Or create animated kaleidoscope\nframes = create_kaleidoscope_animation(\n    base_frame=my_frame,  # or None for demo pattern\n    num_frames=30,\n    segments=8,\n    rotation_speed=1.0\n)\n\n# Simple mirror effects (faster)\nfrom templates.kaleidoscope import apply_simple_mirror\n\nmirrored = apply_simple_mirror(frame, mode='quad')  # 4-way mirror\n# modes: 'horizontal', 'vertical', 'quad', 'radial'\n```\n\n**To compose primitives freely, follow these patterns:**\n```python\n# Example: Bounce + shake for impact\nfor i in range(num_frames):\n    frame = create_blank_frame(480, 480, bg_color)\n\n    # Bounce motion\n    t_bounce = i / (num_frames - 1)\n    y = interpolate(start_y, ground_y, t_bounce, 'bounce_out')\n\n    # Add shake on impact (when y reaches ground)\n    if y >= ground_y - 5:\n        shake_x = math.sin(i * 2) * 10\n        x = center_x + shake_x\n    else:\n        x = center_x\n\n    draw_emoji(frame, '⚽', (x, y), size=60)\n    builder.add_frame(frame)\n```\n\n## Helper Utilities\n\nThese are optional helpers for common needs. **Use, modify, or replace these with custom implementations as needed.**\n\n### GIF Builder (Assembly & Optimization)\n\n```python\nfrom core.gif_builder import GIFBuilder\n\n# Create builder with your chosen settings\nbuilder = GIFBuilder(width=480, height=480, fps=20)\n\n# Add frames (however you created them)\nfor frame in my_frames:\n    builder.add_frame(frame)\n\n# Save with optimization\nbuilder.save('output.gif',\n             num_colors=128,\n             optimize_for_emoji=False)\n```\n\nKey features:\n- Automatic color quantization\n- Duplicate frame removal\n- Size warnings for Slack limits\n- Emoji mode (aggressive optimization)\n\n### Text Rendering\n\nFor small GIFs like emojis, text readability is challenging. A common solution involves adding outlines:\n\n```python\nfrom core.typography import draw_text_with_outline, TYPOGRAPHY_SCALE\n\n# Text with outline (helps readability)\ndraw_text_with_outline(\n    frame, \"BONK!\",\n    position=(240, 100),\n    font_size=TYPOGRAPHY_SCALE['h1'],  # 60px\n    text_color=(255, 68, 68),\n    outline_color=(0, 0, 0),\n    outline_width=4,\n    centered=True\n)\n```\n\nTo implement custom text rendering, use PIL's `ImageDraw.text()` which works fine for larger GIFs.\n\n### Color Management\n\nProfessional-looking GIFs often use cohesive color palettes:\n\n```python\nfrom core.color_palettes import get_palette\n\n# Get a pre-made palette\npalette = get_palette('vibrant')  # or 'pastel', 'dark', 'neon', 'professional'\n\nbg_color = palette['background']\ntext_color = palette['primary']\naccent_color = palette['accent']\n```\n\nTo work with colors directly, use RGB tuples - whatever works for the use case.\n\n### Visual Effects\n\nOptional effects for impact moments:\n\n```python\nfrom core.visual_effects import ParticleSystem, create_impact_flash, create_shockwave_rings\n\n# Particle system\nparticles = ParticleSystem()\nparticles.emit_sparkles(x=240, y=200, count=15)\nparticles.emit_confetti(x=240, y=200, count=20)\n\n# Update and render each frame\nparticles.update()\nparticles.render(frame)\n\n# Flash effect\nframe = create_impact_flash(frame, position=(240, 200), radius=100)\n\n# Shockwave rings\nframe = create_shockwave_rings(frame, position=(240, 200), radii=[30, 60, 90])\n```\n\n### Easing Functions\n\nSmooth motion uses easing instead of linear interpolation:\n\n```python\nfrom core.easing import interpolate\n\n# Object falling (accelerates)\ny = interpolate(start=0, end=400, t=progress, easing='ease_in')\n\n# Object landing (decelerates)\ny = interpolate(start=0, end=400, t=progress, easing='ease_out')\n\n# Bouncing\ny = interpolate(start=0, end=400, t=progress, easing='bounce_out')\n\n# Overshoot (elastic)\nscale = interpolate(start=0.5, end=1.0, t=progress, easing='elastic_out')\n```\n\nAvailable easings: `linear`, `ease_in`, `ease_out`, `ease_in_out`, `bounce_out`, `elastic_out`, `back_out` (overshoot), and more in `core/easing.py`.\n\n### Frame Composition\n\nBasic drawing utilities if you need them:\n\n```python\nfrom core.frame_composer import (\n    create_gradient_background,  # Gradient backgrounds\n    draw_emoji_enhanced,         # Emoji with optional shadow\n    draw_circle_with_shadow,     # Shapes with depth\n    draw_star                    # 5-pointed stars\n)\n\n# Gradient background\nframe = create_gradient_background(480, 480, top_color, bottom_color)\n\n# Emoji with shadow\ndraw_emoji_enhanced(frame, '🎉', position=(200, 200), size=80, shadow=True)\n```\n\n## Optimization Strategies\n\nWhen your GIF is too large:\n\n**For Message GIFs (>2MB):**\n1. Reduce frames (lower FPS or shorter duration)\n2. Reduce colors (128 → 64 colors)\n3. Reduce dimensions (480x480 → 320x320)\n4. Enable duplicate frame removal\n\n**For Emoji GIFs (>64KB) - be aggressive:**\n1. Limit to 10-12 frames total\n2. Use 32-40 colors maximum\n3. Avoid gradients (solid colors compress better)\n4. Simplify design (fewer elements)\n5. Use `optimize_for_emoji=True` in save method\n\n## Example Composition Patterns\n\n### Simple Reaction (Pulsing)\n```python\nbuilder = GIFBuilder(128, 128, 10)\n\nfor i in range(12):\n    frame = Image.new('RGB', (128, 128), (240, 248, 255))\n\n    # Pulsing scale\n    scale = 1.0 + math.sin(i * 0.5) * 0.15\n    size = int(60 * scale)\n\n    draw_emoji_enhanced(frame, '😱', position=(64-size//2, 64-size//2),\n                       size=size, shadow=False)\n    builder.add_frame(frame)\n\nbuilder.save('reaction.gif', num_colors=40, optimize_for_emoji=True)\n\n# Validate\nfrom core.validators import check_slack_size\ncheck_slack_size('reaction.gif', is_emoji=True)\n```\n\n### Action with Impact (Bounce + Flash)\n```python\nbuilder = GIFBuilder(480, 480, 20)\n\n# Phase 1: Object falls\nfor i in range(15):\n    frame = create_gradient_background(480, 480, (240, 248, 255), (200, 230, 255))\n    t = i / 14\n    y = interpolate(0, 350, t, 'ease_in')\n    draw_emoji_enhanced(frame, '⚽', position=(220, int(y)), size=80)\n    builder.add_frame(frame)\n\n# Phase 2: Impact + flash\nfor i in range(8):\n    frame = create_gradient_background(480, 480, (240, 248, 255), (200, 230, 255))\n\n    # Flash on first frames\n    if i < 3:\n        frame = create_impact_flash(frame, (240, 350), radius=120, intensity=0.6)\n\n    draw_emoji_enhanced(frame, '⚽', position=(220, 350), size=80)\n\n    # Text appears\n    if i > 2:\n        draw_text_with_outline(frame, \"GOAL!\", position=(240, 150),\n                              font_size=60, text_color=(255, 68, 68),\n                              outline_color=(0, 0, 0), outline_width=4, centered=True)\n\n    builder.add_frame(frame)\n\nbuilder.save('goal.gif', num_colors=128)\n```\n\n### Combining Primitives (Move + Shake)\n```python\nfrom templates.shake import create_shake_animation\n\n# Create shake animation\nshake_frames = create_shake_animation(\n    object_type='emoji',\n    object_data={'emoji': '😰', 'size': 70},\n    num_frames=20,\n    shake_intensity=12\n)\n\n# Create moving element that triggers the shake\nbuilder = GIFBuilder(480, 480, 20)\nfor i in range(40):\n    t = i / 39\n\n    if i < 20:\n        # Before trigger - use blank frame with moving object\n        frame = create_blank_frame(480, 480, (255, 255, 255))\n        x = interpolate(50, 300, t * 2, 'linear')\n        draw_emoji_enhanced(frame, '🚗', position=(int(x), 300), size=60)\n        draw_emoji_enhanced(frame, '😰', position=(350, 200), size=70)\n    else:\n        # After trigger - use shake frame\n        frame = shake_frames[i - 20]\n        # Add the car in final position\n        draw_emoji_enhanced(frame, '🚗', position=(300, 300), size=60)\n\n    builder.add_frame(frame)\n\nbuilder.save('scare.gif')\n```\n\n## Philosophy\n\nThis toolkit provides building blocks, not rigid recipes. To work with a GIF request:\n\n1. **Understand the creative vision** - What should happen? What's the mood?\n2. **Design the animation** - Break it into phases (anticipation, action, reaction)\n3. **Apply primitives as needed** - Shake, bounce, move, effects - mix freely\n4. **Validate constraints** - Check file size, especially for emoji GIFs\n5. **Iterate if needed** - Reduce frames/colors if over size limits\n\n**The goal is creative freedom within Slack's technical constraints.**\n\n## Dependencies\n\nTo use this toolkit, install these dependencies only if they aren't already present:\n\n```bash\npip install pillow imageio numpy\n```\n"
  },
  {
    "path": "slack-gif-creator/core/color_palettes.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nColor Palettes - Professional, harmonious color schemes for GIFs.\n\nUsing consistent, well-designed color palettes makes GIFs look professional\nand polished instead of random and amateurish.\n\"\"\"\n\nfrom typing import Optional\nimport colorsys\n\n\n# Professional color palettes - hand-picked for GIF compression and visual appeal\n\nVIBRANT = {\n    'primary': (255, 68, 68),      # Bright red\n    'secondary': (255, 168, 0),     # Bright orange\n    'accent': (0, 168, 255),        # Bright blue\n    'success': (68, 255, 68),       # Bright green\n    'background': (240, 248, 255),  # Alice blue\n    'text': (30, 30, 30),           # Almost black\n    'text_light': (255, 255, 255),  # White\n}\n\nPASTEL = {\n    'primary': (255, 179, 186),     # Pastel pink\n    'secondary': (255, 223, 186),   # Pastel peach\n    'accent': (186, 225, 255),      # Pastel blue\n    'success': (186, 255, 201),     # Pastel green\n    'background': (255, 250, 240),  # Floral white\n    'text': (80, 80, 80),           # Dark gray\n    'text_light': (255, 255, 255),  # White\n}\n\nDARK = {\n    'primary': (255, 100, 100),     # Muted red\n    'secondary': (100, 200, 255),   # Muted blue\n    'accent': (255, 200, 100),      # Muted gold\n    'success': (100, 255, 150),     # Muted green\n    'background': (30, 30, 35),     # Almost black\n    'text': (220, 220, 220),        # Light gray\n    'text_light': (255, 255, 255),  # White\n}\n\nNEON = {\n    'primary': (255, 16, 240),      # Neon pink\n    'secondary': (0, 255, 255),     # Cyan\n    'accent': (255, 255, 0),        # Yellow\n    'success': (57, 255, 20),       # Neon green\n    'background': (20, 20, 30),     # Dark blue-black\n    'text': (255, 255, 255),        # White\n    'text_light': (255, 255, 255),  # White\n}\n\nPROFESSIONAL = {\n    'primary': (0, 122, 255),       # System blue\n    'secondary': (88, 86, 214),     # System purple\n    'accent': (255, 149, 0),        # System orange\n    'success': (52, 199, 89),       # System green\n    'background': (255, 255, 255),  # White\n    'text': (0, 0, 0),              # Black\n    'text_light': (255, 255, 255),  # White\n}\n\nWARM = {\n    'primary': (255, 107, 107),     # Coral red\n    'secondary': (255, 159, 64),    # Orange\n    'accent': (255, 218, 121),      # Yellow\n    'success': (106, 176, 76),      # Olive green\n    'background': (255, 246, 229),  # Warm white\n    'text': (51, 51, 51),           # Charcoal\n    'text_light': (255, 255, 255),  # White\n}\n\nCOOL = {\n    'primary': (107, 185, 240),     # Sky blue\n    'secondary': (130, 202, 157),   # Mint\n    'accent': (162, 155, 254),      # Lavender\n    'success': (86, 217, 150),      # Aqua green\n    'background': (240, 248, 255),  # Alice blue\n    'text': (45, 55, 72),           # Dark slate\n    'text_light': (255, 255, 255),  # White\n}\n\nMONOCHROME = {\n    'primary': (80, 80, 80),        # Dark gray\n    'secondary': (130, 130, 130),   # Medium gray\n    'accent': (180, 180, 180),      # Light gray\n    'success': (100, 100, 100),     # Gray\n    'background': (245, 245, 245),  # Off-white\n    'text': (30, 30, 30),           # Almost black\n    'text_light': (255, 255, 255),  # White\n}\n\n# Map of palette names\nPALETTES = {\n    'vibrant': VIBRANT,\n    'pastel': PASTEL,\n    'dark': DARK,\n    'neon': NEON,\n    'professional': PROFESSIONAL,\n    'warm': WARM,\n    'cool': COOL,\n    'monochrome': MONOCHROME,\n}\n\n\ndef get_palette(name: str = 'vibrant') -> dict:\n    \"\"\"\n    Get a color palette by name.\n\n    Args:\n        name: Palette name (vibrant, pastel, dark, neon, professional, warm, cool, monochrome)\n\n    Returns:\n        Dictionary of color roles to RGB tuples\n    \"\"\"\n    return PALETTES.get(name.lower(), VIBRANT)\n\n\ndef get_text_color_for_background(bg_color: tuple[int, int, int]) -> tuple[int, int, int]:\n    \"\"\"\n    Get the best text color (black or white) for a given background.\n\n    Uses luminance calculation to ensure readability.\n\n    Args:\n        bg_color: Background RGB color\n\n    Returns:\n        Text color (black or white) that contrasts well\n    \"\"\"\n    # Calculate relative luminance\n    r, g, b = bg_color\n    luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255\n\n    # Return black for light backgrounds, white for dark\n    return (0, 0, 0) if luminance > 0.5 else (255, 255, 255)\n\n\ndef get_complementary_color(color: tuple[int, int, int]) -> tuple[int, int, int]:\n    \"\"\"\n    Get the complementary (opposite) color on the color wheel.\n\n    Args:\n        color: RGB color tuple\n\n    Returns:\n        Complementary RGB color\n    \"\"\"\n    # Convert to HSV\n    r, g, b = [x / 255.0 for x in color]\n    h, s, v = colorsys.rgb_to_hsv(r, g, b)\n\n    # Rotate hue by 180 degrees (0.5 in 0-1 scale)\n    h_comp = (h + 0.5) % 1.0\n\n    # Convert back to RGB\n    r_comp, g_comp, b_comp = colorsys.hsv_to_rgb(h_comp, s, v)\n    return (int(r_comp * 255), int(g_comp * 255), int(b_comp * 255))\n\n\ndef lighten_color(color: tuple[int, int, int], amount: float = 0.3) -> tuple[int, int, int]:\n    \"\"\"\n    Lighten a color by a given amount.\n\n    Args:\n        color: RGB color tuple\n        amount: Amount to lighten (0.0-1.0)\n\n    Returns:\n        Lightened RGB color\n    \"\"\"\n    r, g, b = color\n    r = min(255, int(r + (255 - r) * amount))\n    g = min(255, int(g + (255 - g) * amount))\n    b = min(255, int(b + (255 - b) * amount))\n    return (r, g, b)\n\n\ndef darken_color(color: tuple[int, int, int], amount: float = 0.3) -> tuple[int, int, int]:\n    \"\"\"\n    Darken a color by a given amount.\n\n    Args:\n        color: RGB color tuple\n        amount: Amount to darken (0.0-1.0)\n\n    Returns:\n        Darkened RGB color\n    \"\"\"\n    r, g, b = color\n    r = max(0, int(r * (1 - amount)))\n    g = max(0, int(g * (1 - amount)))\n    b = max(0, int(b * (1 - amount)))\n    return (r, g, b)\n\n\ndef blend_colors(color1: tuple[int, int, int], color2: tuple[int, int, int],\n                 ratio: float = 0.5) -> tuple[int, int, int]:\n    \"\"\"\n    Blend two colors together.\n\n    Args:\n        color1: First RGB color\n        color2: Second RGB color\n        ratio: Blend ratio (0.0 = all color1, 1.0 = all color2)\n\n    Returns:\n        Blended RGB color\n    \"\"\"\n    r1, g1, b1 = color1\n    r2, g2, b2 = color2\n\n    r = int(r1 * (1 - ratio) + r2 * ratio)\n    g = int(g1 * (1 - ratio) + g2 * ratio)\n    b = int(b1 * (1 - ratio) + b2 * ratio)\n\n    return (r, g, b)\n\n\ndef create_gradient_colors(start_color: tuple[int, int, int],\n                           end_color: tuple[int, int, int],\n                           steps: int) -> list[tuple[int, int, int]]:\n    \"\"\"\n    Create a gradient of colors between two colors.\n\n    Args:\n        start_color: Starting RGB color\n        end_color: Ending RGB color\n        steps: Number of gradient steps\n\n    Returns:\n        List of RGB colors forming gradient\n    \"\"\"\n    colors = []\n    for i in range(steps):\n        ratio = i / (steps - 1) if steps > 1 else 0\n        colors.append(blend_colors(start_color, end_color, ratio))\n    return colors\n\n\n# Impact/emphasis colors that work well across palettes\nIMPACT_COLORS = {\n    'flash': (255, 255, 240),       # Bright flash (cream)\n    'explosion': (255, 150, 0),     # Orange explosion\n    'electricity': (100, 200, 255),  # Electric blue\n    'fire': (255, 100, 0),          # Fire orange-red\n    'success': (50, 255, 100),      # Success green\n    'error': (255, 50, 50),         # Error red\n    'warning': (255, 200, 0),       # Warning yellow\n    'magic': (200, 100, 255),       # Magic purple\n}\n\n\ndef get_impact_color(effect_type: str = 'flash') -> tuple[int, int, int]:\n    \"\"\"\n    Get a color for impact/emphasis effects.\n\n    Args:\n        effect_type: Type of effect (flash, explosion, electricity, etc.)\n\n    Returns:\n        RGB color for effect\n    \"\"\"\n    return IMPACT_COLORS.get(effect_type, IMPACT_COLORS['flash'])\n\n\n# Emoji-safe palettes (work well at 128x128 with 32-64 colors)\nEMOJI_PALETTES = {\n    'simple': [\n        (255, 255, 255),  # White\n        (0, 0, 0),        # Black\n        (255, 100, 100),  # Red\n        (100, 255, 100),  # Green\n        (100, 100, 255),  # Blue\n        (255, 255, 100),  # Yellow\n    ],\n    'vibrant_emoji': [\n        (255, 255, 255),  # White\n        (30, 30, 30),     # Black\n        (255, 68, 68),    # Red\n        (68, 255, 68),    # Green\n        (68, 68, 255),    # Blue\n        (255, 200, 68),   # Gold\n        (255, 68, 200),   # Pink\n        (68, 255, 200),   # Cyan\n    ]\n}\n\n\ndef get_emoji_palette(name: str = 'simple') -> list[tuple[int, int, int]]:\n    \"\"\"\n    Get a limited color palette optimized for emoji GIFs (<64KB).\n\n    Args:\n        name: Palette name (simple, vibrant_emoji)\n\n    Returns:\n        List of RGB colors (6-8 colors)\n    \"\"\"\n    return EMOJI_PALETTES.get(name, EMOJI_PALETTES['simple'])"
  },
  {
    "path": "slack-gif-creator/core/easing.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nEasing Functions - Timing functions for smooth animations.\n\nProvides various easing functions for natural motion and timing.\nAll functions take a value t (0.0 to 1.0) and return eased value (0.0 to 1.0).\n\"\"\"\n\nimport math\n\n\ndef linear(t: float) -> float:\n    \"\"\"Linear interpolation (no easing).\"\"\"\n    return t\n\n\ndef ease_in_quad(t: float) -> float:\n    \"\"\"Quadratic ease-in (slow start, accelerating).\"\"\"\n    return t * t\n\n\ndef ease_out_quad(t: float) -> float:\n    \"\"\"Quadratic ease-out (fast start, decelerating).\"\"\"\n    return t * (2 - t)\n\n\ndef ease_in_out_quad(t: float) -> float:\n    \"\"\"Quadratic ease-in-out (slow start and end).\"\"\"\n    if t < 0.5:\n        return 2 * t * t\n    return -1 + (4 - 2 * t) * t\n\n\ndef ease_in_cubic(t: float) -> float:\n    \"\"\"Cubic ease-in (slow start).\"\"\"\n    return t * t * t\n\n\ndef ease_out_cubic(t: float) -> float:\n    \"\"\"Cubic ease-out (fast start).\"\"\"\n    return (t - 1) * (t - 1) * (t - 1) + 1\n\n\ndef ease_in_out_cubic(t: float) -> float:\n    \"\"\"Cubic ease-in-out.\"\"\"\n    if t < 0.5:\n        return 4 * t * t * t\n    return (t - 1) * (2 * t - 2) * (2 * t - 2) + 1\n\n\ndef ease_in_bounce(t: float) -> float:\n    \"\"\"Bounce ease-in (bouncy start).\"\"\"\n    return 1 - ease_out_bounce(1 - t)\n\n\ndef ease_out_bounce(t: float) -> float:\n    \"\"\"Bounce ease-out (bouncy end).\"\"\"\n    if t < 1 / 2.75:\n        return 7.5625 * t * t\n    elif t < 2 / 2.75:\n        t -= 1.5 / 2.75\n        return 7.5625 * t * t + 0.75\n    elif t < 2.5 / 2.75:\n        t -= 2.25 / 2.75\n        return 7.5625 * t * t + 0.9375\n    else:\n        t -= 2.625 / 2.75\n        return 7.5625 * t * t + 0.984375\n\n\ndef ease_in_out_bounce(t: float) -> float:\n    \"\"\"Bounce ease-in-out.\"\"\"\n    if t < 0.5:\n        return ease_in_bounce(t * 2) * 0.5\n    return ease_out_bounce(t * 2 - 1) * 0.5 + 0.5\n\n\ndef ease_in_elastic(t: float) -> float:\n    \"\"\"Elastic ease-in (spring effect).\"\"\"\n    if t == 0 or t == 1:\n        return t\n    return -math.pow(2, 10 * (t - 1)) * math.sin((t - 1.1) * 5 * math.pi)\n\n\ndef ease_out_elastic(t: float) -> float:\n    \"\"\"Elastic ease-out (spring effect).\"\"\"\n    if t == 0 or t == 1:\n        return t\n    return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) + 1\n\n\ndef ease_in_out_elastic(t: float) -> float:\n    \"\"\"Elastic ease-in-out.\"\"\"\n    if t == 0 or t == 1:\n        return t\n    t = t * 2 - 1\n    if t < 0:\n        return -0.5 * math.pow(2, 10 * t) * math.sin((t - 0.1) * 5 * math.pi)\n    return math.pow(2, -10 * t) * math.sin((t - 0.1) * 5 * math.pi) * 0.5 + 1\n\n\n# Convenience mapping\nEASING_FUNCTIONS = {\n    'linear': linear,\n    'ease_in': ease_in_quad,\n    'ease_out': ease_out_quad,\n    'ease_in_out': ease_in_out_quad,\n    'bounce_in': ease_in_bounce,\n    'bounce_out': ease_out_bounce,\n    'bounce': ease_in_out_bounce,\n    'elastic_in': ease_in_elastic,\n    'elastic_out': ease_out_elastic,\n    'elastic': ease_in_out_elastic,\n}\n\n\ndef get_easing(name: str = 'linear'):\n    \"\"\"Get easing function by name.\"\"\"\n    return EASING_FUNCTIONS.get(name, linear)\n\n\ndef interpolate(start: float, end: float, t: float, easing: str = 'linear') -> float:\n    \"\"\"\n    Interpolate between two values with easing.\n\n    Args:\n        start: Start value\n        end: End value\n        t: Progress from 0.0 to 1.0\n        easing: Name of easing function\n\n    Returns:\n        Interpolated value\n    \"\"\"\n    ease_func = get_easing(easing)\n    eased_t = ease_func(t)\n    return start + (end - start) * eased_t\n\n\ndef ease_back_in(t: float) -> float:\n    \"\"\"Back ease-in (slight overshoot backward before forward motion).\"\"\"\n    c1 = 1.70158\n    c3 = c1 + 1\n    return c3 * t * t * t - c1 * t * t\n\n\ndef ease_back_out(t: float) -> float:\n    \"\"\"Back ease-out (overshoot forward then settle back).\"\"\"\n    c1 = 1.70158\n    c3 = c1 + 1\n    return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2)\n\n\ndef ease_back_in_out(t: float) -> float:\n    \"\"\"Back ease-in-out (overshoot at both ends).\"\"\"\n    c1 = 1.70158\n    c2 = c1 * 1.525\n    if t < 0.5:\n        return (pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2\n    return (pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2\n\n\ndef apply_squash_stretch(base_scale: tuple[float, float], intensity: float,\n                         direction: str = 'vertical') -> tuple[float, float]:\n    \"\"\"\n    Calculate squash and stretch scales for more dynamic animation.\n\n    Args:\n        base_scale: (width_scale, height_scale) base scales\n        intensity: Squash/stretch intensity (0.0-1.0)\n        direction: 'vertical', 'horizontal', or 'both'\n\n    Returns:\n        (width_scale, height_scale) with squash/stretch applied\n    \"\"\"\n    width_scale, height_scale = base_scale\n\n    if direction == 'vertical':\n        # Compress vertically, expand horizontally (preserve volume)\n        height_scale *= (1 - intensity * 0.5)\n        width_scale *= (1 + intensity * 0.5)\n    elif direction == 'horizontal':\n        # Compress horizontally, expand vertically\n        width_scale *= (1 - intensity * 0.5)\n        height_scale *= (1 + intensity * 0.5)\n    elif direction == 'both':\n        # General squash (both dimensions)\n        width_scale *= (1 - intensity * 0.3)\n        height_scale *= (1 - intensity * 0.3)\n\n    return (width_scale, height_scale)\n\n\ndef calculate_arc_motion(start: tuple[float, float], end: tuple[float, float],\n                        height: float, t: float) -> tuple[float, float]:\n    \"\"\"\n    Calculate position along a parabolic arc (natural motion path).\n\n    Args:\n        start: (x, y) starting position\n        end: (x, y) ending position\n        height: Arc height at midpoint (positive = upward)\n        t: Progress (0.0-1.0)\n\n    Returns:\n        (x, y) position along arc\n    \"\"\"\n    x1, y1 = start\n    x2, y2 = end\n\n    # Linear interpolation for x\n    x = x1 + (x2 - x1) * t\n\n    # Parabolic interpolation for y\n    # y = start + progress * (end - start) + arc_offset\n    # Arc offset peaks at t=0.5\n    arc_offset = 4 * height * t * (1 - t)\n    y = y1 + (y2 - y1) * t - arc_offset\n\n    return (x, y)\n\n\n# Add new easing functions to the convenience mapping\nEASING_FUNCTIONS.update({\n    'back_in': ease_back_in,\n    'back_out': ease_back_out,\n    'back_in_out': ease_back_in_out,\n    'anticipate': ease_back_in,     # Alias\n    'overshoot': ease_back_out,     # Alias\n})"
  },
  {
    "path": "slack-gif-creator/core/frame_composer.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nFrame Composer - Utilities for composing visual elements into frames.\n\nProvides functions for drawing shapes, text, emojis, and compositing elements\ntogether to create animation frames.\n\"\"\"\n\nfrom PIL import Image, ImageDraw, ImageFont\nimport numpy as np\nfrom typing import Optional\n\n\ndef create_blank_frame(width: int, height: int, color: tuple[int, int, int] = (255, 255, 255)) -> Image.Image:\n    \"\"\"\n    Create a blank frame with solid color background.\n\n    Args:\n        width: Frame width\n        height: Frame height\n        color: RGB color tuple (default: white)\n\n    Returns:\n        PIL Image\n    \"\"\"\n    return Image.new('RGB', (width, height), color)\n\n\ndef draw_circle(frame: Image.Image, center: tuple[int, int], radius: int,\n                fill_color: Optional[tuple[int, int, int]] = None,\n                outline_color: Optional[tuple[int, int, int]] = None,\n                outline_width: int = 1) -> Image.Image:\n    \"\"\"\n    Draw a circle on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        center: (x, y) center position\n        radius: Circle radius\n        fill_color: RGB fill color (None for no fill)\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = center\n    bbox = [x - radius, y - radius, x + radius, y + radius]\n    draw.ellipse(bbox, fill=fill_color, outline=outline_color, width=outline_width)\n    return frame\n\n\ndef draw_rectangle(frame: Image.Image, top_left: tuple[int, int], bottom_right: tuple[int, int],\n                   fill_color: Optional[tuple[int, int, int]] = None,\n                   outline_color: Optional[tuple[int, int, int]] = None,\n                   outline_width: int = 1) -> Image.Image:\n    \"\"\"\n    Draw a rectangle on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        top_left: (x, y) top-left corner\n        bottom_right: (x, y) bottom-right corner\n        fill_color: RGB fill color (None for no fill)\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    draw.rectangle([top_left, bottom_right], fill=fill_color, outline=outline_color, width=outline_width)\n    return frame\n\n\ndef draw_line(frame: Image.Image, start: tuple[int, int], end: tuple[int, int],\n              color: tuple[int, int, int] = (0, 0, 0), width: int = 2) -> Image.Image:\n    \"\"\"\n    Draw a line on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        start: (x, y) start position\n        end: (x, y) end position\n        color: RGB line color\n        width: Line width in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    draw.line([start, end], fill=color, width=width)\n    return frame\n\n\ndef draw_text(frame: Image.Image, text: str, position: tuple[int, int],\n              font_size: int = 40, color: tuple[int, int, int] = (0, 0, 0),\n              centered: bool = False) -> Image.Image:\n    \"\"\"\n    Draw text on a frame.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position (top-left unless centered=True)\n        font_size: Font size in pixels\n        color: RGB text color\n        centered: If True, center text at position\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n\n    # Try to use default font, fall back to basic if not available\n    try:\n        font = ImageFont.truetype(\"/System/Library/Fonts/Helvetica.ttc\", font_size)\n    except:\n        font = ImageFont.load_default()\n\n    if centered:\n        bbox = draw.textbbox((0, 0), text, font=font)\n        text_width = bbox[2] - bbox[0]\n        text_height = bbox[3] - bbox[1]\n        x = position[0] - text_width // 2\n        y = position[1] - text_height // 2\n        position = (x, y)\n\n    draw.text(position, text, fill=color, font=font)\n    return frame\n\n\ndef draw_emoji(frame: Image.Image, emoji: str, position: tuple[int, int], size: int = 60) -> Image.Image:\n    \"\"\"\n    Draw emoji text on a frame (requires system emoji support).\n\n    Args:\n        frame: PIL Image to draw on\n        emoji: Emoji character(s)\n        position: (x, y) position\n        size: Emoji size in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n\n    # Use Apple Color Emoji font on macOS\n    try:\n        font = ImageFont.truetype(\"/System/Library/Fonts/Apple Color Emoji.ttc\", size)\n    except:\n        # Fallback to text-based emoji\n        font = ImageFont.truetype(\"/System/Library/Fonts/Helvetica.ttc\", size)\n\n    draw.text(position, emoji, font=font, embedded_color=True)\n    return frame\n\n\ndef composite_layers(base: Image.Image, overlay: Image.Image,\n                     position: tuple[int, int] = (0, 0), alpha: float = 1.0) -> Image.Image:\n    \"\"\"\n    Composite one image on top of another.\n\n    Args:\n        base: Base image\n        overlay: Image to overlay on top\n        position: (x, y) position to place overlay\n        alpha: Opacity of overlay (0.0 = transparent, 1.0 = opaque)\n\n    Returns:\n        Composite image\n    \"\"\"\n    # Convert to RGBA for transparency support\n    base_rgba = base.convert('RGBA')\n    overlay_rgba = overlay.convert('RGBA')\n\n    # Apply alpha\n    if alpha < 1.0:\n        overlay_rgba = overlay_rgba.copy()\n        overlay_rgba.putalpha(int(255 * alpha))\n\n    # Paste overlay onto base\n    base_rgba.paste(overlay_rgba, position, overlay_rgba)\n\n    # Convert back to RGB\n    return base_rgba.convert('RGB')\n\n\ndef draw_stick_figure(frame: Image.Image, position: tuple[int, int], scale: float = 1.0,\n                      color: tuple[int, int, int] = (0, 0, 0), line_width: int = 3) -> Image.Image:\n    \"\"\"\n    Draw a simple stick figure.\n\n    Args:\n        frame: PIL Image to draw on\n        position: (x, y) center position of head\n        scale: Size multiplier\n        color: RGB line color\n        line_width: Line width in pixels\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = position\n\n    # Scale dimensions\n    head_radius = int(15 * scale)\n    body_length = int(40 * scale)\n    arm_length = int(25 * scale)\n    leg_length = int(35 * scale)\n    leg_spread = int(15 * scale)\n\n    # Head\n    draw.ellipse([x - head_radius, y - head_radius, x + head_radius, y + head_radius],\n                 outline=color, width=line_width)\n\n    # Body\n    body_start = y + head_radius\n    body_end = body_start + body_length\n    draw.line([(x, body_start), (x, body_end)], fill=color, width=line_width)\n\n    # Arms\n    arm_y = body_start + int(body_length * 0.3)\n    draw.line([(x - arm_length, arm_y), (x + arm_length, arm_y)], fill=color, width=line_width)\n\n    # Legs\n    draw.line([(x, body_end), (x - leg_spread, body_end + leg_length)], fill=color, width=line_width)\n    draw.line([(x, body_end), (x + leg_spread, body_end + leg_length)], fill=color, width=line_width)\n\n    return frame\n\n\ndef create_gradient_background(width: int, height: int,\n                               top_color: tuple[int, int, int],\n                               bottom_color: tuple[int, int, int]) -> Image.Image:\n    \"\"\"\n    Create a vertical gradient background.\n\n    Args:\n        width: Frame width\n        height: Frame height\n        top_color: RGB color at top\n        bottom_color: RGB color at bottom\n\n    Returns:\n        PIL Image with gradient\n    \"\"\"\n    frame = Image.new('RGB', (width, height))\n    draw = ImageDraw.Draw(frame)\n\n    # Calculate color step for each row\n    r1, g1, b1 = top_color\n    r2, g2, b2 = bottom_color\n\n    for y in range(height):\n        # Interpolate color\n        ratio = y / height\n        r = int(r1 * (1 - ratio) + r2 * ratio)\n        g = int(g1 * (1 - ratio) + g2 * ratio)\n        b = int(b1 * (1 - ratio) + b2 * ratio)\n\n        # Draw horizontal line\n        draw.line([(0, y), (width, y)], fill=(r, g, b))\n\n    return frame\n\n\ndef draw_emoji_enhanced(frame: Image.Image, emoji: str, position: tuple[int, int],\n                       size: int = 60, shadow: bool = True,\n                       shadow_offset: tuple[int, int] = (2, 2)) -> Image.Image:\n    \"\"\"\n    Draw emoji with optional shadow for better visual quality.\n\n    Args:\n        frame: PIL Image to draw on\n        emoji: Emoji character(s)\n        position: (x, y) position\n        size: Emoji size in pixels (minimum 12)\n        shadow: Whether to add drop shadow\n        shadow_offset: Shadow offset\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n\n    # Ensure minimum size to avoid font rendering errors\n    size = max(12, size)\n\n    # Use Apple Color Emoji font on macOS\n    try:\n        font = ImageFont.truetype(\"/System/Library/Fonts/Apple Color Emoji.ttc\", size)\n    except:\n        # Fallback to text-based emoji\n        try:\n            font = ImageFont.truetype(\"/System/Library/Fonts/Helvetica.ttc\", size)\n        except:\n            font = ImageFont.load_default()\n\n    # Draw shadow first if enabled\n    if shadow and size >= 20:  # Only draw shadow for larger emojis\n        shadow_pos = (position[0] + shadow_offset[0], position[1] + shadow_offset[1])\n        # Draw semi-transparent shadow (simulated by drawing multiple times)\n        for offset in range(1, 3):\n            try:\n                draw.text((shadow_pos[0] + offset, shadow_pos[1] + offset),\n                         emoji, font=font, embedded_color=True, fill=(0, 0, 0, 100))\n            except:\n                pass  # Skip shadow if it fails\n\n    # Draw main emoji\n    try:\n        draw.text(position, emoji, font=font, embedded_color=True)\n    except:\n        # Fallback to basic drawing if embedded color fails\n        draw.text(position, emoji, font=font, fill=(0, 0, 0))\n\n    return frame\n\n\ndef draw_circle_with_shadow(frame: Image.Image, center: tuple[int, int], radius: int,\n                            fill_color: tuple[int, int, int],\n                            shadow_offset: tuple[int, int] = (3, 3),\n                            shadow_color: tuple[int, int, int] = (0, 0, 0)) -> Image.Image:\n    \"\"\"\n    Draw a circle with drop shadow.\n\n    Args:\n        frame: PIL Image to draw on\n        center: (x, y) center position\n        radius: Circle radius\n        fill_color: RGB fill color\n        shadow_offset: (x, y) shadow offset\n        shadow_color: RGB shadow color\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = center\n\n    # Draw shadow\n    shadow_center = (x + shadow_offset[0], y + shadow_offset[1])\n    shadow_bbox = [\n        shadow_center[0] - radius,\n        shadow_center[1] - radius,\n        shadow_center[0] + radius,\n        shadow_center[1] + radius\n    ]\n    draw.ellipse(shadow_bbox, fill=shadow_color)\n\n    # Draw main circle\n    bbox = [x - radius, y - radius, x + radius, y + radius]\n    draw.ellipse(bbox, fill=fill_color)\n\n    return frame\n\n\ndef draw_rounded_rectangle(frame: Image.Image, top_left: tuple[int, int],\n                          bottom_right: tuple[int, int], radius: int,\n                          fill_color: Optional[tuple[int, int, int]] = None,\n                          outline_color: Optional[tuple[int, int, int]] = None,\n                          outline_width: int = 1) -> Image.Image:\n    \"\"\"\n    Draw a rectangle with rounded corners.\n\n    Args:\n        frame: PIL Image to draw on\n        top_left: (x, y) top-left corner\n        bottom_right: (x, y) bottom-right corner\n        radius: Corner radius\n        fill_color: RGB fill color (None for no fill)\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x1, y1 = top_left\n    x2, y2 = bottom_right\n\n    # Draw rounded rectangle using PIL's built-in method\n    draw.rounded_rectangle([x1, y1, x2, y2], radius=radius,\n                          fill=fill_color, outline=outline_color, width=outline_width)\n\n    return frame\n\n\ndef add_vignette(frame: Image.Image, strength: float = 0.5) -> Image.Image:\n    \"\"\"\n    Add a vignette effect (darkened edges) to frame.\n\n    Args:\n        frame: PIL Image\n        strength: Vignette strength (0.0-1.0)\n\n    Returns:\n        Frame with vignette\n    \"\"\"\n    width, height = frame.size\n\n    # Create radial gradient mask\n    center_x, center_y = width // 2, height // 2\n    max_dist = ((width / 2) ** 2 + (height / 2) ** 2) ** 0.5\n\n    # Create overlay\n    overlay = Image.new('RGB', (width, height), (0, 0, 0))\n    pixels = overlay.load()\n\n    for y in range(height):\n        for x in range(width):\n            # Calculate distance from center\n            dx = x - center_x\n            dy = y - center_y\n            dist = (dx ** 2 + dy ** 2) ** 0.5\n\n            # Calculate vignette value\n            vignette = min(1, (dist / max_dist) * strength)\n            value = int(255 * (1 - vignette))\n            pixels[x, y] = (value, value, value)\n\n    # Blend with original using multiply\n    frame_array = np.array(frame, dtype=np.float32) / 255\n    overlay_array = np.array(overlay, dtype=np.float32) / 255\n\n    result = frame_array * overlay_array\n    result = (result * 255).astype(np.uint8)\n\n    return Image.fromarray(result)\n\n\ndef draw_star(frame: Image.Image, center: tuple[int, int], size: int,\n             fill_color: tuple[int, int, int],\n             outline_color: Optional[tuple[int, int, int]] = None,\n             outline_width: int = 1) -> Image.Image:\n    \"\"\"\n    Draw a 5-pointed star.\n\n    Args:\n        frame: PIL Image to draw on\n        center: (x, y) center position\n        size: Star size (outer radius)\n        fill_color: RGB fill color\n        outline_color: RGB outline color (None for no outline)\n        outline_width: Outline width\n\n    Returns:\n        Modified frame\n    \"\"\"\n    import math\n    draw = ImageDraw.Draw(frame)\n    x, y = center\n\n    # Calculate star points\n    points = []\n    for i in range(10):\n        angle = (i * 36 - 90) * math.pi / 180  # 36 degrees per point, start at top\n        radius = size if i % 2 == 0 else size * 0.4  # Alternate between outer and inner\n        px = x + radius * math.cos(angle)\n        py = y + radius * math.sin(angle)\n        points.append((px, py))\n\n    # Draw star\n    draw.polygon(points, fill=fill_color, outline=outline_color, width=outline_width)\n\n    return frame"
  },
  {
    "path": "slack-gif-creator/core/gif_builder.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nGIF Builder - Core module for assembling frames into GIFs optimized for Slack.\n\nThis module provides the main interface for creating GIFs from programmatically\ngenerated frames, with automatic optimization for Slack's requirements.\n\"\"\"\n\nfrom pathlib import Path\nfrom typing import Optional\nimport imageio.v3 as imageio\nfrom PIL import Image\nimport numpy as np\n\n\nclass GIFBuilder:\n    \"\"\"Builder for creating optimized GIFs from frames.\"\"\"\n\n    def __init__(self, width: int = 480, height: int = 480, fps: int = 15):\n        \"\"\"\n        Initialize GIF builder.\n\n        Args:\n            width: Frame width in pixels\n            height: Frame height in pixels\n            fps: Frames per second\n        \"\"\"\n        self.width = width\n        self.height = height\n        self.fps = fps\n        self.frames: list[np.ndarray] = []\n\n    def add_frame(self, frame: np.ndarray | Image.Image):\n        \"\"\"\n        Add a frame to the GIF.\n\n        Args:\n            frame: Frame as numpy array or PIL Image (will be converted to RGB)\n        \"\"\"\n        if isinstance(frame, Image.Image):\n            frame = np.array(frame.convert('RGB'))\n\n        # Ensure frame is correct size\n        if frame.shape[:2] != (self.height, self.width):\n            pil_frame = Image.fromarray(frame)\n            pil_frame = pil_frame.resize((self.width, self.height), Image.Resampling.LANCZOS)\n            frame = np.array(pil_frame)\n\n        self.frames.append(frame)\n\n    def add_frames(self, frames: list[np.ndarray | Image.Image]):\n        \"\"\"Add multiple frames at once.\"\"\"\n        for frame in frames:\n            self.add_frame(frame)\n\n    def optimize_colors(self, num_colors: int = 128, use_global_palette: bool = True) -> list[np.ndarray]:\n        \"\"\"\n        Reduce colors in all frames using quantization.\n\n        Args:\n            num_colors: Target number of colors (8-256)\n            use_global_palette: Use a single palette for all frames (better compression)\n\n        Returns:\n            List of color-optimized frames\n        \"\"\"\n        optimized = []\n\n        if use_global_palette and len(self.frames) > 1:\n            # Create a global palette from all frames\n            # Sample frames to build palette\n            sample_size = min(5, len(self.frames))\n            sample_indices = [int(i * len(self.frames) / sample_size) for i in range(sample_size)]\n            sample_frames = [self.frames[i] for i in sample_indices]\n\n            # Combine sample frames into a single image for palette generation\n            # Flatten each frame to get all pixels, then stack them\n            all_pixels = np.vstack([f.reshape(-1, 3) for f in sample_frames])  # (total_pixels, 3)\n\n            # Create a properly-shaped RGB image from the pixel data\n            # We'll make a roughly square image from all the pixels\n            total_pixels = len(all_pixels)\n            width = min(512, int(np.sqrt(total_pixels)))  # Reasonable width, max 512\n            height = (total_pixels + width - 1) // width  # Ceiling division\n\n            # Pad if necessary to fill the rectangle\n            pixels_needed = width * height\n            if pixels_needed > total_pixels:\n                padding = np.zeros((pixels_needed - total_pixels, 3), dtype=np.uint8)\n                all_pixels = np.vstack([all_pixels, padding])\n\n            # Reshape to proper RGB image format (H, W, 3)\n            img_array = all_pixels[:pixels_needed].reshape(height, width, 3).astype(np.uint8)\n            combined_img = Image.fromarray(img_array, mode='RGB')\n\n            # Generate global palette\n            global_palette = combined_img.quantize(colors=num_colors, method=2)\n\n            # Apply global palette to all frames\n            for frame in self.frames:\n                pil_frame = Image.fromarray(frame)\n                quantized = pil_frame.quantize(palette=global_palette, dither=1)\n                optimized.append(np.array(quantized.convert('RGB')))\n        else:\n            # Use per-frame quantization\n            for frame in self.frames:\n                pil_frame = Image.fromarray(frame)\n                quantized = pil_frame.quantize(colors=num_colors, method=2, dither=1)\n                optimized.append(np.array(quantized.convert('RGB')))\n\n        return optimized\n\n    def deduplicate_frames(self, threshold: float = 0.995) -> int:\n        \"\"\"\n        Remove duplicate or near-duplicate consecutive frames.\n\n        Args:\n            threshold: Similarity threshold (0.0-1.0). Higher = more strict (0.995 = very similar).\n\n        Returns:\n            Number of frames removed\n        \"\"\"\n        if len(self.frames) < 2:\n            return 0\n\n        deduplicated = [self.frames[0]]\n        removed_count = 0\n\n        for i in range(1, len(self.frames)):\n            # Compare with previous frame\n            prev_frame = np.array(deduplicated[-1], dtype=np.float32)\n            curr_frame = np.array(self.frames[i], dtype=np.float32)\n\n            # Calculate similarity (normalized)\n            diff = np.abs(prev_frame - curr_frame)\n            similarity = 1.0 - (np.mean(diff) / 255.0)\n\n            # Keep frame if sufficiently different\n            # High threshold (0.995) means only remove truly identical frames\n            if similarity < threshold:\n                deduplicated.append(self.frames[i])\n            else:\n                removed_count += 1\n\n        self.frames = deduplicated\n        return removed_count\n\n    def save(self, output_path: str | Path, num_colors: int = 128,\n             optimize_for_emoji: bool = False, remove_duplicates: bool = True) -> dict:\n        \"\"\"\n        Save frames as optimized GIF for Slack.\n\n        Args:\n            output_path: Where to save the GIF\n            num_colors: Number of colors to use (fewer = smaller file)\n            optimize_for_emoji: If True, optimize for <64KB emoji size\n            remove_duplicates: Remove duplicate consecutive frames\n\n        Returns:\n            Dictionary with file info (path, size, dimensions, frame_count)\n        \"\"\"\n        if not self.frames:\n            raise ValueError(\"No frames to save. Add frames with add_frame() first.\")\n\n        output_path = Path(output_path)\n        original_frame_count = len(self.frames)\n\n        # Remove duplicate frames to reduce file size\n        if remove_duplicates:\n            removed = self.deduplicate_frames(threshold=0.98)\n            if removed > 0:\n                print(f\"  Removed {removed} duplicate frames\")\n\n        # Optimize for emoji if requested\n        if optimize_for_emoji:\n            if self.width > 128 or self.height > 128:\n                print(f\"  Resizing from {self.width}x{self.height} to 128x128 for emoji\")\n                self.width = 128\n                self.height = 128\n                # Resize all frames\n                resized_frames = []\n                for frame in self.frames:\n                    pil_frame = Image.fromarray(frame)\n                    pil_frame = pil_frame.resize((128, 128), Image.Resampling.LANCZOS)\n                    resized_frames.append(np.array(pil_frame))\n                self.frames = resized_frames\n            num_colors = min(num_colors, 48)  # More aggressive color limit for emoji\n\n            # More aggressive FPS reduction for emoji\n            if len(self.frames) > 12:\n                print(f\"  Reducing frames from {len(self.frames)} to ~12 for emoji size\")\n                # Keep every nth frame to get close to 12 frames\n                keep_every = max(1, len(self.frames) // 12)\n                self.frames = [self.frames[i] for i in range(0, len(self.frames), keep_every)]\n\n        # Optimize colors with global palette\n        optimized_frames = self.optimize_colors(num_colors, use_global_palette=True)\n\n        # Calculate frame duration in milliseconds\n        frame_duration = 1000 / self.fps\n\n        # Save GIF\n        imageio.imwrite(\n            output_path,\n            optimized_frames,\n            duration=frame_duration,\n            loop=0  # Infinite loop\n        )\n\n        # Get file info\n        file_size_kb = output_path.stat().st_size / 1024\n        file_size_mb = file_size_kb / 1024\n\n        info = {\n            'path': str(output_path),\n            'size_kb': file_size_kb,\n            'size_mb': file_size_mb,\n            'dimensions': f'{self.width}x{self.height}',\n            'frame_count': len(optimized_frames),\n            'fps': self.fps,\n            'duration_seconds': len(optimized_frames) / self.fps,\n            'colors': num_colors\n        }\n\n        # Print info\n        print(f\"\\n✓ GIF created successfully!\")\n        print(f\"  Path: {output_path}\")\n        print(f\"  Size: {file_size_kb:.1f} KB ({file_size_mb:.2f} MB)\")\n        print(f\"  Dimensions: {self.width}x{self.height}\")\n        print(f\"  Frames: {len(optimized_frames)} @ {self.fps} fps\")\n        print(f\"  Duration: {info['duration_seconds']:.1f}s\")\n        print(f\"  Colors: {num_colors}\")\n\n        # Warnings\n        if optimize_for_emoji and file_size_kb > 64:\n            print(f\"\\n⚠️  WARNING: Emoji file size ({file_size_kb:.1f} KB) exceeds 64 KB limit\")\n            print(\"   Try: fewer frames, fewer colors, or simpler design\")\n        elif not optimize_for_emoji and file_size_kb > 2048:\n            print(f\"\\n⚠️  WARNING: File size ({file_size_kb:.1f} KB) is large for Slack\")\n            print(\"   Try: fewer frames, smaller dimensions, or fewer colors\")\n\n        return info\n\n    def clear(self):\n        \"\"\"Clear all frames (useful for creating multiple GIFs).\"\"\"\n        self.frames = []"
  },
  {
    "path": "slack-gif-creator/core/typography.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nTypography System - Professional text rendering with outlines, shadows, and effects.\n\nThis module provides high-quality text rendering that looks crisp and professional\nin GIFs, with outlines for readability and effects for visual impact.\n\"\"\"\n\nfrom PIL import Image, ImageDraw, ImageFont\nfrom typing import Optional\n\n\n# Typography scale - proportional sizing system\nTYPOGRAPHY_SCALE = {\n    'h1': 60,      # Large headers\n    'h2': 48,      # Medium headers\n    'h3': 36,      # Small headers\n    'title': 50,   # Title text\n    'body': 28,    # Body text\n    'small': 20,   # Small text\n    'tiny': 16,    # Tiny text\n}\n\n\ndef get_font(size: int, bold: bool = False) -> ImageFont.FreeTypeFont:\n    \"\"\"\n    Get a font with fallback support.\n\n    Args:\n        size: Font size in pixels\n        bold: Use bold variant if available\n\n    Returns:\n        ImageFont object\n    \"\"\"\n    # Try multiple font paths for cross-platform support\n    font_paths = [\n        # macOS fonts\n        \"/System/Library/Fonts/Helvetica.ttc\",\n        \"/System/Library/Fonts/SF-Pro.ttf\",\n        \"/Library/Fonts/Arial Bold.ttf\" if bold else \"/Library/Fonts/Arial.ttf\",\n        # Linux fonts\n        \"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf\" if bold else \"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf\",\n        # Windows fonts\n        \"C:\\\\Windows\\\\Fonts\\\\arialbd.ttf\" if bold else \"C:\\\\Windows\\\\Fonts\\\\arial.ttf\",\n    ]\n\n    for font_path in font_paths:\n        try:\n            return ImageFont.truetype(font_path, size)\n        except:\n            continue\n\n    # Ultimate fallback\n    return ImageFont.load_default()\n\n\ndef draw_text_with_outline(\n    frame: Image.Image,\n    text: str,\n    position: tuple[int, int],\n    font_size: int = 40,\n    text_color: tuple[int, int, int] = (255, 255, 255),\n    outline_color: tuple[int, int, int] = (0, 0, 0),\n    outline_width: int = 3,\n    centered: bool = False,\n    bold: bool = True\n) -> Image.Image:\n    \"\"\"\n    Draw text with outline for maximum readability.\n\n    This is THE most important function for professional-looking text in GIFs.\n    The outline ensures text is readable on any background.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position\n        font_size: Font size in pixels\n        text_color: RGB color for text fill\n        outline_color: RGB color for outline\n        outline_width: Width of outline in pixels (2-4 recommended)\n        centered: If True, center text at position\n        bold: Use bold font variant\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    font = get_font(font_size, bold=bold)\n\n    # Calculate position for centering\n    if centered:\n        bbox = draw.textbbox((0, 0), text, font=font)\n        text_width = bbox[2] - bbox[0]\n        text_height = bbox[3] - bbox[1]\n        x = position[0] - text_width // 2\n        y = position[1] - text_height // 2\n        position = (x, y)\n\n    # Draw outline by drawing text multiple times offset in all directions\n    x, y = position\n    for offset_x in range(-outline_width, outline_width + 1):\n        for offset_y in range(-outline_width, outline_width + 1):\n            if offset_x != 0 or offset_y != 0:\n                draw.text((x + offset_x, y + offset_y), text, fill=outline_color, font=font)\n\n    # Draw main text on top\n    draw.text(position, text, fill=text_color, font=font)\n\n    return frame\n\n\ndef draw_text_with_shadow(\n    frame: Image.Image,\n    text: str,\n    position: tuple[int, int],\n    font_size: int = 40,\n    text_color: tuple[int, int, int] = (255, 255, 255),\n    shadow_color: tuple[int, int, int] = (0, 0, 0),\n    shadow_offset: tuple[int, int] = (3, 3),\n    centered: bool = False,\n    bold: bool = True\n) -> Image.Image:\n    \"\"\"\n    Draw text with drop shadow for depth.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position\n        font_size: Font size in pixels\n        text_color: RGB color for text\n        shadow_color: RGB color for shadow\n        shadow_offset: (x, y) offset for shadow\n        centered: If True, center text at position\n        bold: Use bold font variant\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    font = get_font(font_size, bold=bold)\n\n    # Calculate position for centering\n    if centered:\n        bbox = draw.textbbox((0, 0), text, font=font)\n        text_width = bbox[2] - bbox[0]\n        text_height = bbox[3] - bbox[1]\n        x = position[0] - text_width // 2\n        y = position[1] - text_height // 2\n        position = (x, y)\n\n    # Draw shadow\n    shadow_pos = (position[0] + shadow_offset[0], position[1] + shadow_offset[1])\n    draw.text(shadow_pos, text, fill=shadow_color, font=font)\n\n    # Draw main text\n    draw.text(position, text, fill=text_color, font=font)\n\n    return frame\n\n\ndef draw_text_with_glow(\n    frame: Image.Image,\n    text: str,\n    position: tuple[int, int],\n    font_size: int = 40,\n    text_color: tuple[int, int, int] = (255, 255, 255),\n    glow_color: tuple[int, int, int] = (255, 200, 0),\n    glow_radius: int = 5,\n    centered: bool = False,\n    bold: bool = True\n) -> Image.Image:\n    \"\"\"\n    Draw text with glow effect for emphasis.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position\n        font_size: Font size in pixels\n        text_color: RGB color for text\n        glow_color: RGB color for glow\n        glow_radius: Radius of glow effect\n        centered: If True, center text at position\n        bold: Use bold font variant\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    font = get_font(font_size, bold=bold)\n\n    # Calculate position for centering\n    if centered:\n        bbox = draw.textbbox((0, 0), text, font=font)\n        text_width = bbox[2] - bbox[0]\n        text_height = bbox[3] - bbox[1]\n        x = position[0] - text_width // 2\n        y = position[1] - text_height // 2\n        position = (x, y)\n\n    # Draw glow layers with decreasing opacity (simulated with same color at different offsets)\n    x, y = position\n    for radius in range(glow_radius, 0, -1):\n        for offset_x in range(-radius, radius + 1):\n            for offset_y in range(-radius, radius + 1):\n                if offset_x != 0 or offset_y != 0:\n                    draw.text((x + offset_x, y + offset_y), text, fill=glow_color, font=font)\n\n    # Draw main text\n    draw.text(position, text, fill=text_color, font=font)\n\n    return frame\n\n\ndef draw_text_in_box(\n    frame: Image.Image,\n    text: str,\n    position: tuple[int, int],\n    font_size: int = 40,\n    text_color: tuple[int, int, int] = (255, 255, 255),\n    box_color: tuple[int, int, int] = (0, 0, 0),\n    box_alpha: float = 0.7,\n    padding: int = 10,\n    centered: bool = True,\n    bold: bool = True\n) -> Image.Image:\n    \"\"\"\n    Draw text in a semi-transparent box for guaranteed readability.\n\n    Args:\n        frame: PIL Image to draw on\n        text: Text to draw\n        position: (x, y) position\n        font_size: Font size in pixels\n        text_color: RGB color for text\n        box_color: RGB color for background box\n        box_alpha: Opacity of box (0.0-1.0)\n        padding: Padding around text in pixels\n        centered: If True, center at position\n        bold: Use bold font variant\n\n    Returns:\n        Modified frame\n    \"\"\"\n    # Create a separate layer for the box with alpha\n    overlay = Image.new('RGBA', frame.size, (0, 0, 0, 0))\n    draw_overlay = ImageDraw.Draw(overlay)\n    draw = ImageDraw.Draw(frame)\n\n    font = get_font(font_size, bold=bold)\n\n    # Get text dimensions\n    bbox = draw.textbbox((0, 0), text, font=font)\n    text_width = bbox[2] - bbox[0]\n    text_height = bbox[3] - bbox[1]\n\n    # Calculate box position\n    if centered:\n        box_x = position[0] - (text_width + padding * 2) // 2\n        box_y = position[1] - (text_height + padding * 2) // 2\n        text_x = position[0] - text_width // 2\n        text_y = position[1] - text_height // 2\n    else:\n        box_x = position[0] - padding\n        box_y = position[1] - padding\n        text_x = position[0]\n        text_y = position[1]\n\n    # Draw semi-transparent box\n    box_coords = [\n        box_x,\n        box_y,\n        box_x + text_width + padding * 2,\n        box_y + text_height + padding * 2\n    ]\n    alpha_value = int(255 * box_alpha)\n    draw_overlay.rectangle(box_coords, fill=(*box_color, alpha_value))\n\n    # Composite overlay onto frame\n    frame_rgba = frame.convert('RGBA')\n    frame_rgba = Image.alpha_composite(frame_rgba, overlay)\n    frame = frame_rgba.convert('RGB')\n\n    # Draw text on top\n    draw = ImageDraw.Draw(frame)\n    draw.text((text_x, text_y), text, fill=text_color, font=font)\n\n    return frame\n\n\ndef get_text_size(text: str, font_size: int, bold: bool = True) -> tuple[int, int]:\n    \"\"\"\n    Get the dimensions of text without drawing it.\n\n    Args:\n        text: Text to measure\n        font_size: Font size in pixels\n        bold: Use bold font variant\n\n    Returns:\n        (width, height) tuple\n    \"\"\"\n    font = get_font(font_size, bold=bold)\n    # Create temporary image to measure\n    temp_img = Image.new('RGB', (1, 1))\n    draw = ImageDraw.Draw(temp_img)\n    bbox = draw.textbbox((0, 0), text, font=font)\n    width = bbox[2] - bbox[0]\n    height = bbox[3] - bbox[1]\n    return (width, height)\n\n\ndef get_optimal_font_size(text: str, max_width: int, max_height: int,\n                          start_size: int = 60) -> int:\n    \"\"\"\n    Find the largest font size that fits within given dimensions.\n\n    Args:\n        text: Text to size\n        max_width: Maximum width in pixels\n        max_height: Maximum height in pixels\n        start_size: Starting font size to try\n\n    Returns:\n        Optimal font size\n    \"\"\"\n    font_size = start_size\n    while font_size > 10:\n        width, height = get_text_size(text, font_size)\n        if width <= max_width and height <= max_height:\n            return font_size\n        font_size -= 2\n    return 10  # Minimum font size\n\n\ndef scale_font_for_frame(base_size: int, frame_width: int, frame_height: int) -> int:\n    \"\"\"\n    Scale font size proportionally to frame dimensions.\n\n    Useful for maintaining relative text size across different GIF dimensions.\n\n    Args:\n        base_size: Base font size for 480x480 frame\n        frame_width: Actual frame width\n        frame_height: Actual frame height\n\n    Returns:\n        Scaled font size\n    \"\"\"\n    # Use average dimension for scaling\n    avg_dimension = (frame_width + frame_height) / 2\n    base_dimension = 480  # Reference dimension\n    scale_factor = avg_dimension / base_dimension\n    return max(10, int(base_size * scale_factor))"
  },
  {
    "path": "slack-gif-creator/core/validators.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nValidators - Check if GIFs meet Slack's requirements.\n\nThese validators help ensure your GIFs meet Slack's size and dimension constraints.\n\"\"\"\n\nfrom pathlib import Path\n\n\ndef check_slack_size(gif_path: str | Path, is_emoji: bool = True) -> tuple[bool, dict]:\n    \"\"\"\n    Check if GIF meets Slack size limits.\n\n    Args:\n        gif_path: Path to GIF file\n        is_emoji: True for emoji GIF (64KB limit), False for message GIF (2MB limit)\n\n    Returns:\n        Tuple of (passes: bool, info: dict with details)\n    \"\"\"\n    gif_path = Path(gif_path)\n\n    if not gif_path.exists():\n        return False, {'error': f'File not found: {gif_path}'}\n\n    size_bytes = gif_path.stat().st_size\n    size_kb = size_bytes / 1024\n    size_mb = size_kb / 1024\n\n    limit_kb = 64 if is_emoji else 2048\n    limit_mb = limit_kb / 1024\n\n    passes = size_kb <= limit_kb\n\n    info = {\n        'size_bytes': size_bytes,\n        'size_kb': size_kb,\n        'size_mb': size_mb,\n        'limit_kb': limit_kb,\n        'limit_mb': limit_mb,\n        'passes': passes,\n        'type': 'emoji' if is_emoji else 'message'\n    }\n\n    # Print feedback\n    if passes:\n        print(f\"✓ {size_kb:.1f} KB - within {limit_kb} KB limit\")\n    else:\n        print(f\"✗ {size_kb:.1f} KB - exceeds {limit_kb} KB limit\")\n        overage_kb = size_kb - limit_kb\n        overage_percent = (overage_kb / limit_kb) * 100\n        print(f\"  Over by: {overage_kb:.1f} KB ({overage_percent:.1f}%)\")\n        print(f\"  Try: fewer frames, fewer colors, or simpler design\")\n\n    return passes, info\n\n\ndef validate_dimensions(width: int, height: int, is_emoji: bool = True) -> tuple[bool, dict]:\n    \"\"\"\n    Check if dimensions are suitable for Slack.\n\n    Args:\n        width: Frame width in pixels\n        height: Frame height in pixels\n        is_emoji: True for emoji GIF, False for message GIF\n\n    Returns:\n        Tuple of (passes: bool, info: dict with details)\n    \"\"\"\n    info = {\n        'width': width,\n        'height': height,\n        'is_square': width == height,\n        'type': 'emoji' if is_emoji else 'message'\n    }\n\n    if is_emoji:\n        # Emoji GIFs should be 128x128\n        optimal = width == height == 128\n        acceptable = width == height and 64 <= width <= 128\n\n        info['optimal'] = optimal\n        info['acceptable'] = acceptable\n\n        if optimal:\n            print(f\"✓ {width}x{height} - optimal for emoji\")\n            passes = True\n        elif acceptable:\n            print(f\"⚠ {width}x{height} - acceptable but 128x128 is optimal\")\n            passes = True\n        else:\n            print(f\"✗ {width}x{height} - emoji should be square, 128x128 recommended\")\n            passes = False\n    else:\n        # Message GIFs should be square-ish and reasonable size\n        aspect_ratio = max(width, height) / min(width, height) if min(width, height) > 0 else float('inf')\n        reasonable_size = 320 <= min(width, height) <= 640\n\n        info['aspect_ratio'] = aspect_ratio\n        info['reasonable_size'] = reasonable_size\n\n        # Check if roughly square (within 2:1 ratio)\n        is_square_ish = aspect_ratio <= 2.0\n\n        if is_square_ish and reasonable_size:\n            print(f\"✓ {width}x{height} - good for message GIF\")\n            passes = True\n        elif is_square_ish:\n            print(f\"⚠ {width}x{height} - square-ish but unusual size\")\n            passes = True\n        elif reasonable_size:\n            print(f\"⚠ {width}x{height} - good size but not square-ish\")\n            passes = True\n        else:\n            print(f\"✗ {width}x{height} - unusual dimensions for Slack\")\n            passes = False\n\n    return passes, info\n\n\ndef validate_gif(gif_path: str | Path, is_emoji: bool = True) -> tuple[bool, dict]:\n    \"\"\"\n    Run all validations on a GIF file.\n\n    Args:\n        gif_path: Path to GIF file\n        is_emoji: True for emoji GIF, False for message GIF\n\n    Returns:\n        Tuple of (all_pass: bool, results: dict)\n    \"\"\"\n    from PIL import Image\n\n    gif_path = Path(gif_path)\n\n    if not gif_path.exists():\n        return False, {'error': f'File not found: {gif_path}'}\n\n    print(f\"\\nValidating {gif_path.name} as {'emoji' if is_emoji else 'message'} GIF:\")\n    print(\"=\" * 60)\n\n    # Check file size\n    size_pass, size_info = check_slack_size(gif_path, is_emoji)\n\n    # Check dimensions\n    try:\n        with Image.open(gif_path) as img:\n            width, height = img.size\n            dim_pass, dim_info = validate_dimensions(width, height, is_emoji)\n\n            # Count frames\n            frame_count = 0\n            try:\n                while True:\n                    img.seek(frame_count)\n                    frame_count += 1\n            except EOFError:\n                pass\n\n            # Get duration if available\n            try:\n                duration_ms = img.info.get('duration', 100)\n                total_duration = (duration_ms * frame_count) / 1000\n                fps = frame_count / total_duration if total_duration > 0 else 0\n            except:\n                duration_ms = None\n                total_duration = None\n                fps = None\n\n    except Exception as e:\n        return False, {'error': f'Failed to read GIF: {e}'}\n\n    print(f\"\\nFrames: {frame_count}\")\n    if total_duration:\n        print(f\"Duration: {total_duration:.1f}s @ {fps:.1f} fps\")\n\n    all_pass = size_pass and dim_pass\n\n    results = {\n        'file': str(gif_path),\n        'passes': all_pass,\n        'size': size_info,\n        'dimensions': dim_info,\n        'frame_count': frame_count,\n        'duration_seconds': total_duration,\n        'fps': fps\n    }\n\n    print(\"=\" * 60)\n    if all_pass:\n        print(\"✓ All validations passed!\")\n    else:\n        print(\"✗ Some validations failed\")\n    print()\n\n    return all_pass, results\n\n\ndef get_optimization_suggestions(results: dict) -> list[str]:\n    \"\"\"\n    Get suggestions for optimizing a GIF based on validation results.\n\n    Args:\n        results: Results dict from validate_gif()\n\n    Returns:\n        List of suggestion strings\n    \"\"\"\n    suggestions = []\n\n    if not results.get('passes', False):\n        size_info = results.get('size', {})\n        dim_info = results.get('dimensions', {})\n\n        # Size suggestions\n        if not size_info.get('passes', True):\n            overage = size_info['size_kb'] - size_info['limit_kb']\n            if size_info['type'] == 'emoji':\n                suggestions.append(f\"Reduce file size by {overage:.1f} KB:\")\n                suggestions.append(\"  - Limit to 10-12 frames\")\n                suggestions.append(\"  - Use 32-40 colors maximum\")\n                suggestions.append(\"  - Remove gradients (solid colors compress better)\")\n                suggestions.append(\"  - Simplify design\")\n            else:\n                suggestions.append(f\"Reduce file size by {overage:.1f} KB:\")\n                suggestions.append(\"  - Reduce frame count or FPS\")\n                suggestions.append(\"  - Use fewer colors (128 → 64)\")\n                suggestions.append(\"  - Reduce dimensions\")\n\n        # Dimension suggestions\n        if not dim_info.get('optimal', True) and dim_info.get('type') == 'emoji':\n            suggestions.append(\"For optimal emoji GIF:\")\n            suggestions.append(\"  - Use 128x128 dimensions\")\n            suggestions.append(\"  - Ensure square aspect ratio\")\n\n    return suggestions\n\n\n# Convenience function for quick checks\ndef is_slack_ready(gif_path: str | Path, is_emoji: bool = True, verbose: bool = True) -> bool:\n    \"\"\"\n    Quick check if GIF is ready for Slack.\n\n    Args:\n        gif_path: Path to GIF file\n        is_emoji: True for emoji GIF, False for message GIF\n        verbose: Print detailed feedback\n\n    Returns:\n        True if ready, False otherwise\n    \"\"\"\n    if verbose:\n        passes, results = validate_gif(gif_path, is_emoji)\n        if not passes:\n            suggestions = get_optimization_suggestions(results)\n            if suggestions:\n                print(\"\\nSuggestions:\")\n                for suggestion in suggestions:\n                    print(suggestion)\n        return passes\n    else:\n        size_pass, _ = check_slack_size(gif_path, is_emoji)\n        return size_pass\n"
  },
  {
    "path": "slack-gif-creator/core/visual_effects.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nVisual Effects - Particles, motion blur, impacts, and other effects for GIFs.\n\nThis module provides high-impact visual effects that make animations feel\nprofessional and dynamic while keeping file sizes reasonable.\n\"\"\"\n\nfrom PIL import Image, ImageDraw, ImageFilter\nimport numpy as np\nimport math\nimport random\nfrom typing import Optional\n\n\nclass Particle:\n    \"\"\"A single particle in a particle system.\"\"\"\n\n    def __init__(self, x: float, y: float, vx: float, vy: float,\n                 lifetime: float, color: tuple[int, int, int],\n                 size: int = 3, shape: str = 'circle'):\n        \"\"\"\n        Initialize a particle.\n\n        Args:\n            x, y: Starting position\n            vx, vy: Velocity\n            lifetime: How long particle lives (in frames)\n            color: RGB color\n            size: Particle size in pixels\n            shape: 'circle', 'square', or 'star'\n        \"\"\"\n        self.x = x\n        self.y = y\n        self.vx = vx\n        self.vy = vy\n        self.lifetime = lifetime\n        self.max_lifetime = lifetime\n        self.color = color\n        self.size = size\n        self.shape = shape\n        self.gravity = 0.5  # Pixels per frame squared\n        self.drag = 0.98    # Velocity multiplier per frame\n\n    def update(self):\n        \"\"\"Update particle position and lifetime.\"\"\"\n        # Apply physics\n        self.vy += self.gravity\n        self.vx *= self.drag\n        self.vy *= self.drag\n\n        # Update position\n        self.x += self.vx\n        self.y += self.vy\n\n        # Decrease lifetime\n        self.lifetime -= 1\n\n    def is_alive(self) -> bool:\n        \"\"\"Check if particle is still alive.\"\"\"\n        return self.lifetime > 0\n\n    def get_alpha(self) -> float:\n        \"\"\"Get particle opacity based on lifetime.\"\"\"\n        return max(0, min(1, self.lifetime / self.max_lifetime))\n\n    def render(self, frame: Image.Image):\n        \"\"\"\n        Render particle to frame.\n\n        Args:\n            frame: PIL Image to draw on\n        \"\"\"\n        if not self.is_alive():\n            return\n\n        draw = ImageDraw.Draw(frame)\n        alpha = self.get_alpha()\n\n        # Calculate faded color\n        color = tuple(int(c * alpha) for c in self.color)\n\n        # Draw based on shape\n        x, y = int(self.x), int(self.y)\n        size = max(1, int(self.size * alpha))\n\n        if self.shape == 'circle':\n            bbox = [x - size, y - size, x + size, y + size]\n            draw.ellipse(bbox, fill=color)\n        elif self.shape == 'square':\n            bbox = [x - size, y - size, x + size, y + size]\n            draw.rectangle(bbox, fill=color)\n        elif self.shape == 'star':\n            # Simple 4-point star\n            points = [\n                (x, y - size),\n                (x - size // 2, y),\n                (x, y),\n                (x, y + size),\n                (x, y),\n                (x + size // 2, y),\n            ]\n            draw.line(points, fill=color, width=2)\n\n\nclass ParticleSystem:\n    \"\"\"Manages a collection of particles.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize particle system.\"\"\"\n        self.particles: list[Particle] = []\n\n    def emit(self, x: int, y: int, count: int = 10,\n             spread: float = 2.0, speed: float = 5.0,\n             color: tuple[int, int, int] = (255, 200, 0),\n             lifetime: float = 20.0, size: int = 3, shape: str = 'circle'):\n        \"\"\"\n        Emit a burst of particles.\n\n        Args:\n            x, y: Emission position\n            count: Number of particles to emit\n            spread: Angle spread (radians)\n            speed: Initial speed\n            color: Particle color\n            lifetime: Particle lifetime in frames\n            size: Particle size\n            shape: Particle shape\n        \"\"\"\n        for _ in range(count):\n            # Random angle and speed\n            angle = random.uniform(0, 2 * math.pi)\n            vel_mag = random.uniform(speed * 0.5, speed * 1.5)\n            vx = math.cos(angle) * vel_mag\n            vy = math.sin(angle) * vel_mag\n\n            # Random lifetime variation\n            life = random.uniform(lifetime * 0.7, lifetime * 1.3)\n\n            particle = Particle(x, y, vx, vy, life, color, size, shape)\n            self.particles.append(particle)\n\n    def emit_confetti(self, x: int, y: int, count: int = 20,\n                      colors: Optional[list[tuple[int, int, int]]] = None):\n        \"\"\"\n        Emit confetti particles (colorful, falling).\n\n        Args:\n            x, y: Emission position\n            count: Number of confetti pieces\n            colors: List of colors (random if None)\n        \"\"\"\n        if colors is None:\n            colors = [\n                (255, 107, 107), (255, 159, 64), (255, 218, 121),\n                (107, 185, 240), (162, 155, 254), (255, 182, 193)\n            ]\n\n        for _ in range(count):\n            color = random.choice(colors)\n            vx = random.uniform(-3, 3)\n            vy = random.uniform(-8, -2)\n            shape = random.choice(['square', 'circle'])\n            size = random.randint(2, 4)\n            lifetime = random.uniform(40, 60)\n\n            particle = Particle(x, y, vx, vy, lifetime, color, size, shape)\n            particle.gravity = 0.3  # Lighter gravity for confetti\n            self.particles.append(particle)\n\n    def emit_sparkles(self, x: int, y: int, count: int = 15):\n        \"\"\"\n        Emit sparkle particles (twinkling stars).\n\n        Args:\n            x, y: Emission position\n            count: Number of sparkles\n        \"\"\"\n        colors = [(255, 255, 200), (255, 255, 255), (255, 255, 150)]\n\n        for _ in range(count):\n            color = random.choice(colors)\n            angle = random.uniform(0, 2 * math.pi)\n            speed = random.uniform(1, 3)\n            vx = math.cos(angle) * speed\n            vy = math.sin(angle) * speed\n            lifetime = random.uniform(15, 30)\n\n            particle = Particle(x, y, vx, vy, lifetime, color, 2, 'star')\n            particle.gravity = 0\n            particle.drag = 0.95\n            self.particles.append(particle)\n\n    def update(self):\n        \"\"\"Update all particles.\"\"\"\n        # Update alive particles\n        for particle in self.particles:\n            particle.update()\n\n        # Remove dead particles\n        self.particles = [p for p in self.particles if p.is_alive()]\n\n    def render(self, frame: Image.Image):\n        \"\"\"Render all particles to frame.\"\"\"\n        for particle in self.particles:\n            particle.render(frame)\n\n    def get_particle_count(self) -> int:\n        \"\"\"Get number of active particles.\"\"\"\n        return len(self.particles)\n\n\ndef add_motion_blur(frame: Image.Image, prev_frame: Optional[Image.Image],\n                    blur_amount: float = 0.5) -> Image.Image:\n    \"\"\"\n    Add motion blur by blending with previous frame.\n\n    Args:\n        frame: Current frame\n        prev_frame: Previous frame (None for first frame)\n        blur_amount: Amount of blur (0.0-1.0)\n\n    Returns:\n        Frame with motion blur applied\n    \"\"\"\n    if prev_frame is None:\n        return frame\n\n    # Blend current frame with previous frame\n    frame_array = np.array(frame, dtype=np.float32)\n    prev_array = np.array(prev_frame, dtype=np.float32)\n\n    blended = frame_array * (1 - blur_amount) + prev_array * blur_amount\n    blended = np.clip(blended, 0, 255).astype(np.uint8)\n\n    return Image.fromarray(blended)\n\n\ndef create_impact_flash(frame: Image.Image, position: tuple[int, int],\n                        radius: int = 100, intensity: float = 0.7) -> Image.Image:\n    \"\"\"\n    Create a bright flash effect at impact point.\n\n    Args:\n        frame: PIL Image to draw on\n        position: Center of flash\n        radius: Flash radius\n        intensity: Flash intensity (0.0-1.0)\n\n    Returns:\n        Modified frame\n    \"\"\"\n    # Create overlay\n    overlay = Image.new('RGBA', frame.size, (0, 0, 0, 0))\n    draw = ImageDraw.Draw(overlay)\n\n    x, y = position\n\n    # Draw concentric circles with decreasing opacity\n    num_circles = 5\n    for i in range(num_circles):\n        alpha = int(255 * intensity * (1 - i / num_circles))\n        r = radius * (1 - i / num_circles)\n        color = (255, 255, 240, alpha)  # Warm white\n\n        bbox = [x - r, y - r, x + r, y + r]\n        draw.ellipse(bbox, fill=color)\n\n    # Composite onto frame\n    frame_rgba = frame.convert('RGBA')\n    frame_rgba = Image.alpha_composite(frame_rgba, overlay)\n    return frame_rgba.convert('RGB')\n\n\ndef create_shockwave_rings(frame: Image.Image, position: tuple[int, int],\n                           radii: list[int], color: tuple[int, int, int] = (255, 200, 0),\n                           width: int = 3) -> Image.Image:\n    \"\"\"\n    Create expanding ring effects.\n\n    Args:\n        frame: PIL Image to draw on\n        position: Center of rings\n        radii: List of ring radii\n        color: Ring color\n        width: Ring width\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = position\n\n    for radius in radii:\n        bbox = [x - radius, y - radius, x + radius, y + radius]\n        draw.ellipse(bbox, outline=color, width=width)\n\n    return frame\n\n\ndef create_explosion_effect(frame: Image.Image, position: tuple[int, int],\n                            radius: int, progress: float,\n                            color: tuple[int, int, int] = (255, 150, 0)) -> Image.Image:\n    \"\"\"\n    Create an explosion effect that expands and fades.\n\n    Args:\n        frame: PIL Image to draw on\n        position: Explosion center\n        radius: Maximum radius\n        progress: Animation progress (0.0-1.0)\n        color: Explosion color\n\n    Returns:\n        Modified frame\n    \"\"\"\n    current_radius = int(radius * progress)\n    fade = 1 - progress\n\n    # Create overlay\n    overlay = Image.new('RGBA', frame.size, (0, 0, 0, 0))\n    draw = ImageDraw.Draw(overlay)\n\n    x, y = position\n\n    # Draw expanding circle with fade\n    alpha = int(255 * fade)\n    r, g, b = color\n    circle_color = (r, g, b, alpha)\n\n    bbox = [x - current_radius, y - current_radius, x + current_radius, y + current_radius]\n    draw.ellipse(bbox, fill=circle_color)\n\n    # Composite\n    frame_rgba = frame.convert('RGBA')\n    frame_rgba = Image.alpha_composite(frame_rgba, overlay)\n    return frame_rgba.convert('RGB')\n\n\ndef add_glow_effect(frame: Image.Image, mask_color: tuple[int, int, int],\n                    glow_color: tuple[int, int, int],\n                    blur_radius: int = 10) -> Image.Image:\n    \"\"\"\n    Add a glow effect to areas of a specific color.\n\n    Args:\n        frame: PIL Image\n        mask_color: Color to create glow around\n        glow_color: Color of glow\n        blur_radius: Blur amount\n\n    Returns:\n        Frame with glow\n    \"\"\"\n    # Create mask of target color\n    frame_array = np.array(frame)\n    mask = np.all(frame_array == mask_color, axis=-1)\n\n    # Create glow layer\n    glow = Image.new('RGB', frame.size, (0, 0, 0))\n    glow_array = np.array(glow)\n    glow_array[mask] = glow_color\n    glow = Image.fromarray(glow_array)\n\n    # Blur the glow\n    glow = glow.filter(ImageFilter.GaussianBlur(blur_radius))\n\n    # Blend with original\n    blended = Image.blend(frame, glow, 0.5)\n    return blended\n\n\ndef add_drop_shadow(frame: Image.Image, object_bounds: tuple[int, int, int, int],\n                    shadow_offset: tuple[int, int] = (5, 5),\n                    shadow_color: tuple[int, int, int] = (0, 0, 0),\n                    blur: int = 5) -> Image.Image:\n    \"\"\"\n    Add drop shadow to an object.\n\n    Args:\n        frame: PIL Image\n        object_bounds: (x1, y1, x2, y2) bounds of object\n        shadow_offset: (x, y) offset of shadow\n        shadow_color: Shadow color\n        blur: Shadow blur amount\n\n    Returns:\n        Frame with shadow\n    \"\"\"\n    # Extract object\n    x1, y1, x2, y2 = object_bounds\n    obj = frame.crop((x1, y1, x2, y2))\n\n    # Create shadow\n    shadow = Image.new('RGBA', obj.size, (*shadow_color, 180))\n\n    # Create frame with alpha\n    frame_rgba = frame.convert('RGBA')\n\n    # Paste shadow\n    shadow_pos = (x1 + shadow_offset[0], y1 + shadow_offset[1])\n    frame_rgba.paste(shadow, shadow_pos, shadow)\n\n    # Paste object on top\n    frame_rgba.paste(obj, (x1, y1))\n\n    return frame_rgba.convert('RGB')\n\n\ndef create_speed_lines(frame: Image.Image, position: tuple[int, int],\n                       direction: float, length: int = 50,\n                       count: int = 5, color: tuple[int, int, int] = (200, 200, 200)) -> Image.Image:\n    \"\"\"\n    Create speed lines for motion effect.\n\n    Args:\n        frame: PIL Image to draw on\n        position: Center position\n        direction: Angle in radians (0 = right, pi/2 = down)\n        length: Line length\n        count: Number of lines\n        color: Line color\n\n    Returns:\n        Modified frame\n    \"\"\"\n    draw = ImageDraw.Draw(frame)\n    x, y = position\n\n    # Opposite direction (lines trail behind)\n    trail_angle = direction + math.pi\n\n    for i in range(count):\n        # Offset from center\n        offset_angle = trail_angle + random.uniform(-0.3, 0.3)\n        offset_dist = random.uniform(10, 30)\n        start_x = x + math.cos(offset_angle) * offset_dist\n        start_y = y + math.sin(offset_angle) * offset_dist\n\n        # End point\n        line_length = random.uniform(length * 0.7, length * 1.3)\n        end_x = start_x + math.cos(trail_angle) * line_length\n        end_y = start_y + math.sin(trail_angle) * line_length\n\n        # Draw line with varying opacity\n        alpha = random.randint(100, 200)\n        width = random.randint(1, 3)\n\n        # Simple line (full opacity simulation)\n        draw.line([(start_x, start_y), (end_x, end_y)], fill=color, width=width)\n\n    return frame\n\n\ndef create_screen_shake_offset(intensity: int, frame_index: int) -> tuple[int, int]:\n    \"\"\"\n    Calculate screen shake offset for a frame.\n\n    Args:\n        intensity: Shake intensity in pixels\n        frame_index: Current frame number\n\n    Returns:\n        (x, y) offset tuple\n    \"\"\"\n    # Use frame index for deterministic but random-looking shake\n    random.seed(frame_index)\n    offset_x = random.randint(-intensity, intensity)\n    offset_y = random.randint(-intensity, intensity)\n    random.seed()  # Reset seed\n    return (offset_x, offset_y)\n\n\ndef apply_screen_shake(frame: Image.Image, intensity: int, frame_index: int) -> Image.Image:\n    \"\"\"\n    Apply screen shake effect to entire frame.\n\n    Args:\n        frame: PIL Image\n        intensity: Shake intensity\n        frame_index: Current frame number\n\n    Returns:\n        Shaken frame\n    \"\"\"\n    offset_x, offset_y = create_screen_shake_offset(intensity, frame_index)\n\n    # Create new frame with background\n    shaken = Image.new('RGB', frame.size, (0, 0, 0))\n\n    # Paste original frame with offset\n    shaken.paste(frame, (offset_x, offset_y))\n\n    return shaken"
  },
  {
    "path": "slack-gif-creator/requirements.txt",
    "content": "pillow>=10.0.0\nimageio>=2.31.0\nimageio-ffmpeg>=0.4.9\nnumpy>=1.24.0"
  },
  {
    "path": "slack-gif-creator/templates/bounce.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nBounce Animation Template - Creates bouncing motion for objects.\n\nUse this to make objects bounce up and down or horizontally with realistic physics.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\n# Add parent directory to path\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_circle, draw_emoji\nfrom core.easing import ease_out_bounce, interpolate\n\n\ndef create_bounce_animation(\n    object_type: str = 'circle',\n    object_data: dict = None,\n    num_frames: int = 30,\n    bounce_height: int = 150,\n    ground_y: int = 350,\n    start_x: int = 240,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list:\n    \"\"\"\n    Create frames for a bouncing animation.\n\n    Args:\n        object_type: 'circle', 'emoji', or 'custom'\n        object_data: Data for the object (e.g., {'radius': 30, 'color': (255, 0, 0)})\n        num_frames: Number of frames in the animation\n        bounce_height: Maximum height of bounce\n        ground_y: Y position of ground\n        start_x: X position (or starting X if moving horizontally)\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'circle':\n            object_data = {'radius': 30, 'color': (255, 100, 100)}\n        elif object_type == 'emoji':\n            object_data = {'emoji': '⚽', 'size': 60}\n\n    for i in range(num_frames):\n        # Create blank frame\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Calculate progress (0.0 to 1.0)\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate Y position using bounce easing\n        y = ground_y - int(ease_out_bounce(t) * bounce_height)\n\n        # Draw object\n        if object_type == 'circle':\n            draw_circle(\n                frame,\n                center=(start_x, y),\n                radius=object_data['radius'],\n                fill_color=object_data['color']\n            )\n        elif object_type == 'emoji':\n            draw_emoji(\n                frame,\n                emoji=object_data['emoji'],\n                position=(start_x - object_data['size'] // 2, y - object_data['size'] // 2),\n                size=object_data['size']\n            )\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating bouncing ball GIF...\")\n\n    # Create GIF builder\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Generate bounce animation\n    frames = create_bounce_animation(\n        object_type='circle',\n        object_data={'radius': 40, 'color': (255, 100, 100)},\n        num_frames=40,\n        bounce_height=200\n    )\n\n    # Add frames to builder\n    builder.add_frames(frames)\n\n    # Save GIF\n    builder.save('bounce_test.gif', num_colors=64)"
  },
  {
    "path": "slack-gif-creator/templates/explode.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nExplode Animation - Break objects into pieces that fly outward.\n\nCreates explosion, shatter, and particle burst effects.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\nimport random\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image, ImageDraw\nimport numpy as np\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.visual_effects import ParticleSystem\nfrom core.easing import interpolate\n\n\ndef create_explode_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    explode_type: str = 'burst',  # 'burst', 'shatter', 'dissolve', 'implode'\n    num_pieces: int = 20,\n    explosion_speed: float = 5.0,\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create explosion animation.\n\n    Args:\n        object_type: 'emoji', 'circle', 'text'\n        object_data: Object configuration\n        num_frames: Number of frames\n        explode_type: Type of explosion\n        num_pieces: Number of pieces/particles\n        explosion_speed: Speed of explosion\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '💣', 'size': 100}\n\n    # Generate pieces/particles\n    pieces = []\n    for _ in range(num_pieces):\n        angle = random.uniform(0, 2 * math.pi)\n        speed = random.uniform(explosion_speed * 0.5, explosion_speed * 1.5)\n        vx = math.cos(angle) * speed\n        vy = math.sin(angle) * speed\n        size = random.randint(3, 12)\n        color = (\n            random.randint(100, 255),\n            random.randint(100, 255),\n            random.randint(100, 255)\n        )\n        rotation_speed = random.uniform(-20, 20)\n\n        pieces.append({\n            'vx': vx,\n            'vy': vy,\n            'size': size,\n            'color': color,\n            'rotation': 0,\n            'rotation_speed': rotation_speed\n        })\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n        draw = ImageDraw.Draw(frame)\n\n        if explode_type == 'burst':\n            # Show object at start, then explode\n            if t < 0.2:\n                # Object still intact\n                scale = interpolate(1.0, 1.2, t / 0.2, 'ease_out')\n                if object_type == 'emoji':\n                    size = int(object_data['size'] * scale)\n                    draw_emoji_enhanced(\n                        frame,\n                        emoji=object_data['emoji'],\n                        position=(center_pos[0] - size // 2, center_pos[1] - size // 2),\n                        size=size,\n                        shadow=False\n                    )\n            else:\n                # Exploded - draw pieces\n                explosion_t = (t - 0.2) / 0.8\n                for piece in pieces:\n                    # Update position\n                    x = center_pos[0] + piece['vx'] * explosion_t * 50\n                    y = center_pos[1] + piece['vy'] * explosion_t * 50 + 0.5 * 300 * explosion_t ** 2  # Gravity\n\n                    # Fade out\n                    alpha = 1.0 - explosion_t\n                    if alpha > 0:\n                        color = tuple(int(c * alpha) for c in piece['color'])\n                        size = int(piece['size'] * (1 - explosion_t * 0.5))\n\n                        draw.ellipse(\n                            [x - size, y - size, x + size, y + size],\n                            fill=color\n                        )\n\n        elif explode_type == 'shatter':\n            # Break into geometric pieces\n            if t < 0.15:\n                # Object intact\n                if object_type == 'emoji':\n                    draw_emoji_enhanced(\n                        frame,\n                        emoji=object_data['emoji'],\n                        position=(center_pos[0] - object_data['size'] // 2,\n                                center_pos[1] - object_data['size'] // 2),\n                        size=object_data['size'],\n                        shadow=False\n                    )\n            else:\n                # Shattered\n                shatter_t = (t - 0.15) / 0.85\n\n                # Draw triangular shards\n                for piece in pieces[:min(10, len(pieces))]:\n                    x = center_pos[0] + piece['vx'] * shatter_t * 30\n                    y = center_pos[1] + piece['vy'] * shatter_t * 30 + 0.5 * 200 * shatter_t ** 2\n\n                    # Update rotation\n                    rotation = piece['rotation_speed'] * shatter_t * 100\n\n                    # Draw triangle shard\n                    shard_size = piece['size'] * 2\n                    points = []\n                    for j in range(3):\n                        angle = (rotation + j * 120) * math.pi / 180\n                        px = x + shard_size * math.cos(angle)\n                        py = y + shard_size * math.sin(angle)\n                        points.append((px, py))\n\n                    alpha = 1.0 - shatter_t\n                    if alpha > 0:\n                        color = tuple(int(c * alpha) for c in piece['color'])\n                        draw.polygon(points, fill=color)\n\n        elif explode_type == 'dissolve':\n            # Dissolve into particles\n            dissolve_scale = interpolate(1.0, 0.0, t, 'ease_in')\n\n            if dissolve_scale > 0.1:\n                # Draw fading object\n                if object_type == 'emoji':\n                    size = int(object_data['size'] * dissolve_scale)\n                    size = max(12, size)\n\n                    emoji_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n                    draw_emoji_enhanced(\n                        emoji_canvas,\n                        emoji=object_data['emoji'],\n                        position=(center_pos[0] - size // 2, center_pos[1] - size // 2),\n                        size=size,\n                        shadow=False\n                    )\n\n                    # Apply opacity\n                    from templates.fade import apply_opacity\n                    emoji_canvas = apply_opacity(emoji_canvas, dissolve_scale)\n\n                    frame_rgba = frame.convert('RGBA')\n                    frame = Image.alpha_composite(frame_rgba, emoji_canvas)\n                    frame = frame.convert('RGB')\n                    draw = ImageDraw.Draw(frame)\n\n            # Draw outward-moving particles\n            for piece in pieces:\n                x = center_pos[0] + piece['vx'] * t * 40\n                y = center_pos[1] + piece['vy'] * t * 40\n\n                alpha = 1.0 - t\n                if alpha > 0:\n                    color = tuple(int(c * alpha) for c in piece['color'])\n                    size = int(piece['size'] * (1 - t * 0.5))\n                    draw.ellipse(\n                        [x - size, y - size, x + size, y + size],\n                        fill=color\n                    )\n\n        elif explode_type == 'implode':\n            # Reverse explosion - pieces fly inward\n            if t < 0.7:\n                # Pieces converging\n                implode_t = 1.0 - (t / 0.7)\n                for piece in pieces:\n                    x = center_pos[0] + piece['vx'] * implode_t * 50\n                    y = center_pos[1] + piece['vy'] * implode_t * 50\n\n                    alpha = 1.0 - (1.0 - implode_t) * 0.5\n                    color = tuple(int(c * alpha) for c in piece['color'])\n                    size = int(piece['size'] * alpha)\n\n                    draw.ellipse(\n                        [x - size, y - size, x + size, y + size],\n                        fill=color\n                    )\n            else:\n                # Object reforms\n                reform_t = (t - 0.7) / 0.3\n                scale = interpolate(0.5, 1.0, reform_t, 'elastic_out')\n\n                if object_type == 'emoji':\n                    size = int(object_data['size'] * scale)\n                    draw_emoji_enhanced(\n                        frame,\n                        emoji=object_data['emoji'],\n                        position=(center_pos[0] - size // 2, center_pos[1] - size // 2),\n                        size=size,\n                        shadow=False\n                    )\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_particle_burst(\n    num_frames: int = 25,\n    particle_count: int = 30,\n    center_pos: tuple[int, int] = (240, 240),\n    colors: list[tuple[int, int, int]] | None = None,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create simple particle burst effect.\n\n    Args:\n        num_frames: Number of frames\n        particle_count: Number of particles\n        center_pos: Burst center\n        colors: Particle colors (None for random)\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    particles = ParticleSystem()\n\n    # Emit particles\n    if colors is None:\n        from core.color_palettes import get_palette\n        palette = get_palette('vibrant')\n        colors = [palette['primary'], palette['secondary'], palette['accent']]\n\n    for _ in range(particle_count):\n        color = random.choice(colors)\n        particles.emit(\n            center_pos[0], center_pos[1],\n            count=1,\n            speed=random.uniform(3, 8),\n            color=color,\n            lifetime=random.uniform(20, 30),\n            size=random.randint(3, 8),\n            shape='star'\n        )\n\n    frames = []\n    for _ in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        particles.update()\n        particles.render(frame)\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating explode animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Burst\n    frames = create_explode_animation(\n        object_type='emoji',\n        object_data={'emoji': '💣', 'size': 100},\n        num_frames=30,\n        explode_type='burst',\n        num_pieces=25\n    )\n    builder.add_frames(frames)\n    builder.save('explode_burst.gif', num_colors=128)\n\n    # Example 2: Shatter\n    builder.clear()\n    frames = create_explode_animation(\n        object_type='emoji',\n        object_data={'emoji': '🪟', 'size': 100},\n        num_frames=30,\n        explode_type='shatter',\n        num_pieces=12\n    )\n    builder.add_frames(frames)\n    builder.save('explode_shatter.gif', num_colors=128)\n\n    # Example 3: Particle burst\n    builder.clear()\n    frames = create_particle_burst(num_frames=25, particle_count=40)\n    builder.add_frames(frames)\n    builder.save('explode_particles.gif', num_colors=128)\n\n    print(\"Created explode animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/fade.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nFade Animation - Fade in, fade out, and crossfade effects.\n\nCreates smooth opacity transitions for appearing, disappearing, and transitioning.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image, ImageDraw\nimport numpy as np\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.easing import interpolate\n\n\ndef create_fade_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    fade_type: str = 'in',  # 'in', 'out', 'in_out', 'blink'\n    easing: str = 'ease_in_out',\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create fade animation.\n\n    Args:\n        object_type: 'emoji', 'text', 'image'\n        object_data: Object configuration\n        num_frames: Number of frames\n        fade_type: Type of fade effect\n        easing: Easing function\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '✨', 'size': 100}\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate opacity based on fade type\n        if fade_type == 'in':\n            opacity = interpolate(0, 1, t, easing)\n        elif fade_type == 'out':\n            opacity = interpolate(1, 0, t, easing)\n        elif fade_type == 'in_out':\n            if t < 0.5:\n                opacity = interpolate(0, 1, t * 2, easing)\n            else:\n                opacity = interpolate(1, 0, (t - 0.5) * 2, easing)\n        elif fade_type == 'blink':\n            # Quick fade out and back in\n            if t < 0.2:\n                opacity = interpolate(1, 0, t / 0.2, 'ease_in')\n            elif t < 0.4:\n                opacity = interpolate(0, 1, (t - 0.2) / 0.2, 'ease_out')\n            else:\n                opacity = 1.0\n        else:\n            opacity = interpolate(0, 1, t, easing)\n\n        # Create background\n        frame_bg = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Create object layer with transparency\n        if object_type == 'emoji':\n            # Create RGBA canvas for emoji\n            emoji_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n            emoji_size = object_data['size']\n            draw_emoji_enhanced(\n                emoji_canvas,\n                emoji=object_data['emoji'],\n                position=(center_pos[0] - emoji_size // 2, center_pos[1] - emoji_size // 2),\n                size=emoji_size,\n                shadow=object_data.get('shadow', False)\n            )\n\n            # Apply opacity\n            emoji_canvas = apply_opacity(emoji_canvas, opacity)\n\n            # Composite onto background\n            frame_bg_rgba = frame_bg.convert('RGBA')\n            frame = Image.alpha_composite(frame_bg_rgba, emoji_canvas)\n            frame = frame.convert('RGB')\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n\n            # Create text on separate layer\n            text_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n            text_canvas_rgb = text_canvas.convert('RGB')\n            text_canvas_rgb.paste(bg_color, (0, 0, frame_width, frame_height))\n\n            draw_text_with_outline(\n                text_canvas_rgb,\n                text=object_data.get('text', 'FADE'),\n                position=center_pos,\n                font_size=object_data.get('font_size', 60),\n                text_color=object_data.get('text_color', (0, 0, 0)),\n                outline_color=object_data.get('outline_color', (255, 255, 255)),\n                outline_width=3,\n                centered=True\n            )\n\n            # Convert to RGBA and make background transparent\n            text_canvas = text_canvas_rgb.convert('RGBA')\n            data = text_canvas.getdata()\n            new_data = []\n            for item in data:\n                if item[:3] == bg_color:\n                    new_data.append((255, 255, 255, 0))\n                else:\n                    new_data.append(item)\n            text_canvas.putdata(new_data)\n\n            # Apply opacity\n            text_canvas = apply_opacity(text_canvas, opacity)\n\n            # Composite\n            frame_bg_rgba = frame_bg.convert('RGBA')\n            frame = Image.alpha_composite(frame_bg_rgba, text_canvas)\n            frame = frame.convert('RGB')\n\n        else:\n            frame = frame_bg\n\n        frames.append(frame)\n\n    return frames\n\n\ndef apply_opacity(image: Image.Image, opacity: float) -> Image.Image:\n    \"\"\"\n    Apply opacity to an RGBA image.\n\n    Args:\n        image: RGBA image\n        opacity: Opacity value (0.0 to 1.0)\n\n    Returns:\n        Image with adjusted opacity\n    \"\"\"\n    if image.mode != 'RGBA':\n        image = image.convert('RGBA')\n\n    # Get alpha channel\n    r, g, b, a = image.split()\n\n    # Multiply alpha by opacity\n    a_array = np.array(a, dtype=np.float32)\n    a_array = a_array * opacity\n    a = Image.fromarray(a_array.astype(np.uint8))\n\n    # Merge back\n    return Image.merge('RGBA', (r, g, b, a))\n\n\ndef create_crossfade(\n    object1_data: dict,\n    object2_data: dict,\n    num_frames: int = 30,\n    easing: str = 'ease_in_out',\n    object_type: str = 'emoji',\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Crossfade between two objects.\n\n    Args:\n        object1_data: First object configuration\n        object2_data: Second object configuration\n        num_frames: Number of frames\n        easing: Easing function\n        object_type: Type of objects\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate opacities\n        opacity1 = interpolate(1, 0, t, easing)\n        opacity2 = interpolate(0, 1, t, easing)\n\n        # Create background\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        if object_type == 'emoji':\n            # Create first emoji\n            emoji1_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n            size1 = object1_data['size']\n            draw_emoji_enhanced(\n                emoji1_canvas,\n                emoji=object1_data['emoji'],\n                position=(center_pos[0] - size1 // 2, center_pos[1] - size1 // 2),\n                size=size1,\n                shadow=False\n            )\n            emoji1_canvas = apply_opacity(emoji1_canvas, opacity1)\n\n            # Create second emoji\n            emoji2_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n            size2 = object2_data['size']\n            draw_emoji_enhanced(\n                emoji2_canvas,\n                emoji=object2_data['emoji'],\n                position=(center_pos[0] - size2 // 2, center_pos[1] - size2 // 2),\n                size=size2,\n                shadow=False\n            )\n            emoji2_canvas = apply_opacity(emoji2_canvas, opacity2)\n\n            # Composite both\n            frame_rgba = frame.convert('RGBA')\n            frame_rgba = Image.alpha_composite(frame_rgba, emoji1_canvas)\n            frame_rgba = Image.alpha_composite(frame_rgba, emoji2_canvas)\n            frame = frame_rgba.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_fade_to_color(\n    start_color: tuple[int, int, int],\n    end_color: tuple[int, int, int],\n    num_frames: int = 20,\n    easing: str = 'linear',\n    frame_width: int = 480,\n    frame_height: int = 480\n) -> list[Image.Image]:\n    \"\"\"\n    Fade from one solid color to another.\n\n    Args:\n        start_color: Starting RGB color\n        end_color: Ending RGB color\n        num_frames: Number of frames\n        easing: Easing function\n        frame_width: Frame width\n        frame_height: Frame height\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Interpolate each color channel\n        r = int(interpolate(start_color[0], end_color[0], t, easing))\n        g = int(interpolate(start_color[1], end_color[1], t, easing))\n        b = int(interpolate(start_color[2], end_color[2], t, easing))\n\n        color = (r, g, b)\n        frame = create_blank_frame(frame_width, frame_height, color)\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating fade animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Fade in\n    frames = create_fade_animation(\n        object_type='emoji',\n        object_data={'emoji': '✨', 'size': 120},\n        num_frames=30,\n        fade_type='in',\n        easing='ease_out'\n    )\n    builder.add_frames(frames)\n    builder.save('fade_in.gif', num_colors=128)\n\n    # Example 2: Crossfade\n    builder.clear()\n    frames = create_crossfade(\n        object1_data={'emoji': '😊', 'size': 100},\n        object2_data={'emoji': '😂', 'size': 100},\n        num_frames=30,\n        object_type='emoji'\n    )\n    builder.add_frames(frames)\n    builder.save('fade_crossfade.gif', num_colors=128)\n\n    # Example 3: Blink\n    builder.clear()\n    frames = create_fade_animation(\n        object_type='emoji',\n        object_data={'emoji': '👀', 'size': 100},\n        num_frames=20,\n        fade_type='blink'\n    )\n    builder.add_frames(frames)\n    builder.save('fade_blink.gif', num_colors=128)\n\n    print(\"Created fade animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/flip.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nFlip Animation - 3D-style card flip and rotation effects.\n\nCreates horizontal and vertical flips with perspective.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.easing import interpolate\n\n\ndef create_flip_animation(\n    object1_data: dict,\n    object2_data: dict | None = None,\n    num_frames: int = 30,\n    flip_axis: str = 'horizontal',  # 'horizontal', 'vertical'\n    easing: str = 'ease_in_out',\n    object_type: str = 'emoji',\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create 3D-style flip animation.\n\n    Args:\n        object1_data: First object (front side)\n        object2_data: Second object (back side, None = same as front)\n        num_frames: Number of frames\n        flip_axis: Axis to flip around\n        easing: Easing function\n        object_type: Type of objects\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    if object2_data is None:\n        object2_data = object1_data\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Calculate rotation angle (0 to 180 degrees)\n        angle = interpolate(0, 180, t, easing)\n\n        # Determine which side is visible and calculate scale\n        if angle < 90:\n            # Front side visible\n            current_object = object1_data\n            scale_factor = math.cos(math.radians(angle))\n        else:\n            # Back side visible\n            current_object = object2_data\n            scale_factor = abs(math.cos(math.radians(angle)))\n\n        # Don't draw when edge-on (very thin)\n        if scale_factor < 0.05:\n            frames.append(frame)\n            continue\n\n        if object_type == 'emoji':\n            size = current_object['size']\n\n            # Create emoji on canvas\n            canvas_size = size * 2\n            emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            draw_emoji_enhanced(\n                emoji_canvas,\n                emoji=current_object['emoji'],\n                position=(canvas_size // 2 - size // 2, canvas_size // 2 - size // 2),\n                size=size,\n                shadow=False\n            )\n\n            # Apply flip scaling\n            if flip_axis == 'horizontal':\n                # Scale horizontally for horizontal flip\n                new_width = max(1, int(canvas_size * scale_factor))\n                new_height = canvas_size\n            else:\n                # Scale vertically for vertical flip\n                new_width = canvas_size\n                new_height = max(1, int(canvas_size * scale_factor))\n\n            # Resize to simulate 3D rotation\n            emoji_scaled = emoji_canvas.resize((new_width, new_height), Image.LANCZOS)\n\n            # Position centered\n            paste_x = center_pos[0] - new_width // 2\n            paste_y = center_pos[1] - new_height // 2\n\n            # Composite onto frame\n            frame_rgba = frame.convert('RGBA')\n            frame_rgba.paste(emoji_scaled, (paste_x, paste_y), emoji_scaled)\n            frame = frame_rgba.convert('RGB')\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n\n            # Create text on canvas\n            text = current_object.get('text', 'FLIP')\n            font_size = current_object.get('font_size', 50)\n\n            canvas_size = max(frame_width, frame_height)\n            text_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            # Draw on RGB for text rendering\n            text_canvas_rgb = text_canvas.convert('RGB')\n            text_canvas_rgb.paste(bg_color, (0, 0, canvas_size, canvas_size))\n\n            draw_text_with_outline(\n                text_canvas_rgb,\n                text=text,\n                position=(canvas_size // 2, canvas_size // 2),\n                font_size=font_size,\n                text_color=current_object.get('text_color', (0, 0, 0)),\n                outline_color=current_object.get('outline_color', (255, 255, 255)),\n                outline_width=3,\n                centered=True\n            )\n\n            # Make background transparent\n            text_canvas = text_canvas_rgb.convert('RGBA')\n            data = text_canvas.getdata()\n            new_data = []\n            for item in data:\n                if item[:3] == bg_color:\n                    new_data.append((255, 255, 255, 0))\n                else:\n                    new_data.append(item)\n            text_canvas.putdata(new_data)\n\n            # Apply flip scaling\n            if flip_axis == 'horizontal':\n                new_width = max(1, int(canvas_size * scale_factor))\n                new_height = canvas_size\n            else:\n                new_width = canvas_size\n                new_height = max(1, int(canvas_size * scale_factor))\n\n            text_scaled = text_canvas.resize((new_width, new_height), Image.LANCZOS)\n\n            # Center and crop\n            if flip_axis == 'horizontal':\n                left = (new_width - frame_width) // 2 if new_width > frame_width else 0\n                top = (canvas_size - frame_height) // 2\n                paste_x = center_pos[0] - min(new_width, frame_width) // 2\n                paste_y = 0\n\n                text_cropped = text_scaled.crop((\n                    left,\n                    top,\n                    left + min(new_width, frame_width),\n                    top + frame_height\n                ))\n            else:\n                left = (canvas_size - frame_width) // 2\n                top = (new_height - frame_height) // 2 if new_height > frame_height else 0\n                paste_x = 0\n                paste_y = center_pos[1] - min(new_height, frame_height) // 2\n\n                text_cropped = text_scaled.crop((\n                    left,\n                    top,\n                    left + frame_width,\n                    top + min(new_height, frame_height)\n                ))\n\n            frame_rgba = frame.convert('RGBA')\n            frame_rgba.paste(text_cropped, (paste_x, paste_y), text_cropped)\n            frame = frame_rgba.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_quick_flip(\n    emoji_front: str,\n    emoji_back: str,\n    num_frames: int = 20,\n    frame_size: int = 128\n) -> list[Image.Image]:\n    \"\"\"\n    Create quick flip for emoji GIFs.\n\n    Args:\n        emoji_front: Front emoji\n        emoji_back: Back emoji\n        num_frames: Number of frames\n        frame_size: Frame size (square)\n\n    Returns:\n        List of frames\n    \"\"\"\n    return create_flip_animation(\n        object1_data={'emoji': emoji_front, 'size': 80},\n        object2_data={'emoji': emoji_back, 'size': 80},\n        num_frames=num_frames,\n        flip_axis='horizontal',\n        easing='ease_in_out',\n        object_type='emoji',\n        center_pos=(frame_size // 2, frame_size // 2),\n        frame_width=frame_size,\n        frame_height=frame_size,\n        bg_color=(255, 255, 255)\n    )\n\n\ndef create_nope_flip(\n    num_frames: int = 25,\n    frame_width: int = 480,\n    frame_height: int = 480\n) -> list[Image.Image]:\n    \"\"\"\n    Create \"nope\" reaction flip (like flipping table).\n\n    Args:\n        num_frames: Number of frames\n        frame_width: Frame width\n        frame_height: Frame height\n\n    Returns:\n        List of frames\n    \"\"\"\n    return create_flip_animation(\n        object1_data={'text': 'NOPE', 'font_size': 80, 'text_color': (255, 50, 50)},\n        object2_data={'text': 'NOPE', 'font_size': 80, 'text_color': (255, 50, 50)},\n        num_frames=num_frames,\n        flip_axis='horizontal',\n        easing='ease_out',\n        object_type='text',\n        frame_width=frame_width,\n        frame_height=frame_height,\n        bg_color=(255, 255, 255)\n    )\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating flip animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Emoji flip\n    frames = create_flip_animation(\n        object1_data={'emoji': '😊', 'size': 120},\n        object2_data={'emoji': '😂', 'size': 120},\n        num_frames=30,\n        flip_axis='horizontal',\n        object_type='emoji'\n    )\n    builder.add_frames(frames)\n    builder.save('flip_emoji.gif', num_colors=128)\n\n    # Example 2: Text flip\n    builder.clear()\n    frames = create_flip_animation(\n        object1_data={'text': 'YES', 'font_size': 80, 'text_color': (100, 200, 100)},\n        object2_data={'text': 'NO', 'font_size': 80, 'text_color': (200, 100, 100)},\n        num_frames=30,\n        flip_axis='vertical',\n        object_type='text'\n    )\n    builder.add_frames(frames)\n    builder.save('flip_text.gif', num_colors=128)\n\n    # Example 3: Quick flip (emoji size)\n    builder = GIFBuilder(width=128, height=128, fps=15)\n    frames = create_quick_flip('👍', '👎', num_frames=20)\n    builder.add_frames(frames)\n    builder.save('flip_quick.gif', num_colors=48, optimize_for_emoji=True)\n\n    print(\"Created flip animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/kaleidoscope.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nKaleidoscope Effect - Create mirror/rotation effects.\n\nApply kaleidoscope effects to frames or objects for psychedelic visuals.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image, ImageOps, ImageDraw\nimport numpy as np\n\n\ndef apply_kaleidoscope(frame: Image.Image, segments: int = 8,\n                       center: tuple[int, int] | None = None) -> Image.Image:\n    \"\"\"\n    Apply kaleidoscope effect by mirroring/rotating frame sections.\n\n    Args:\n        frame: Input frame\n        segments: Number of mirror segments (4, 6, 8, 12 work well)\n        center: Center point for effect (None = frame center)\n\n    Returns:\n        Frame with kaleidoscope effect\n    \"\"\"\n    width, height = frame.size\n\n    if center is None:\n        center = (width // 2, height // 2)\n\n    # Create output frame\n    output = Image.new('RGB', (width, height))\n\n    # Calculate angle per segment\n    angle_per_segment = 360 / segments\n\n    # For simplicity, we'll create a radial mirror effect\n    # A full implementation would rotate and mirror properly\n    # This is a simplified version that creates interesting patterns\n\n    # Convert to numpy for easier manipulation\n    frame_array = np.array(frame)\n    output_array = np.zeros_like(frame_array)\n\n    center_x, center_y = center\n\n    # Create wedge mask and mirror it\n    for y in range(height):\n        for x in range(width):\n            # Calculate angle from center\n            dx = x - center_x\n            dy = y - center_y\n\n            angle = (math.degrees(math.atan2(dy, dx)) + 180) % 360\n            distance = math.sqrt(dx * dx + dy * dy)\n\n            # Which segment does this pixel belong to?\n            segment = int(angle / angle_per_segment)\n\n            # Mirror angle within segment\n            segment_angle = angle % angle_per_segment\n            if segment % 2 == 1:  # Mirror every other segment\n                segment_angle = angle_per_segment - segment_angle\n\n            # Calculate source position\n            source_angle = segment_angle + (segment // 2) * angle_per_segment * 2\n            source_angle_rad = math.radians(source_angle - 180)\n\n            source_x = int(center_x + distance * math.cos(source_angle_rad))\n            source_y = int(center_y + distance * math.sin(source_angle_rad))\n\n            # Bounds check\n            if 0 <= source_x < width and 0 <= source_y < height:\n                output_array[y, x] = frame_array[source_y, source_x]\n            else:\n                output_array[y, x] = frame_array[y, x]\n\n    return Image.fromarray(output_array)\n\n\ndef apply_simple_mirror(frame: Image.Image, mode: str = 'quad') -> Image.Image:\n    \"\"\"\n    Apply simple mirror effect (faster than full kaleidoscope).\n\n    Args:\n        frame: Input frame\n        mode: 'horizontal', 'vertical', 'quad' (4-way), 'radial'\n\n    Returns:\n        Mirrored frame\n    \"\"\"\n    width, height = frame.size\n    center_x, center_y = width // 2, height // 2\n\n    if mode == 'horizontal':\n        # Mirror left half to right\n        left_half = frame.crop((0, 0, center_x, height))\n        left_flipped = ImageOps.mirror(left_half)\n        result = frame.copy()\n        result.paste(left_flipped, (center_x, 0))\n        return result\n\n    elif mode == 'vertical':\n        # Mirror top half to bottom\n        top_half = frame.crop((0, 0, width, center_y))\n        top_flipped = ImageOps.flip(top_half)\n        result = frame.copy()\n        result.paste(top_flipped, (0, center_y))\n        return result\n\n    elif mode == 'quad':\n        # 4-way mirror (top-left quadrant mirrored to all)\n        quad = frame.crop((0, 0, center_x, center_y))\n\n        result = Image.new('RGB', (width, height))\n\n        # Top-left (original)\n        result.paste(quad, (0, 0))\n\n        # Top-right (horizontal mirror)\n        result.paste(ImageOps.mirror(quad), (center_x, 0))\n\n        # Bottom-left (vertical mirror)\n        result.paste(ImageOps.flip(quad), (0, center_y))\n\n        # Bottom-right (both mirrors)\n        result.paste(ImageOps.flip(ImageOps.mirror(quad)), (center_x, center_y))\n\n        return result\n\n    else:\n        return frame\n\n\ndef create_kaleidoscope_animation(\n    base_frame: Image.Image | None = None,\n    num_frames: int = 30,\n    segments: int = 8,\n    rotation_speed: float = 1.0,\n    width: int = 480,\n    height: int = 480\n) -> list[Image.Image]:\n    \"\"\"\n    Create animated kaleidoscope effect.\n\n    Args:\n        base_frame: Frame to apply effect to (or None for demo pattern)\n        num_frames: Number of frames\n        segments: Kaleidoscope segments\n        rotation_speed: How fast pattern rotates (0.5-2.0)\n        width: Frame width if generating demo\n        height: Frame height if generating demo\n\n    Returns:\n        List of frames with kaleidoscope effect\n    \"\"\"\n    frames = []\n\n    # Create demo pattern if no base frame\n    if base_frame is None:\n        base_frame = Image.new('RGB', (width, height), (255, 255, 255))\n        draw = ImageDraw.Draw(base_frame)\n\n        # Draw some colored shapes\n        from core.color_palettes import get_palette\n        palette = get_palette('vibrant')\n\n        colors = [palette['primary'], palette['secondary'], palette['accent']]\n\n        for i, color in enumerate(colors):\n            x = width // 2 + int(100 * math.cos(i * 2 * math.pi / 3))\n            y = height // 2 + int(100 * math.sin(i * 2 * math.pi / 3))\n            draw.ellipse([x - 40, y - 40, x + 40, y + 40], fill=color)\n\n    # Rotate base frame and apply kaleidoscope\n    for i in range(num_frames):\n        angle = (i / num_frames) * 360 * rotation_speed\n\n        # Rotate base frame\n        rotated = base_frame.rotate(angle, resample=Image.BICUBIC)\n\n        # Apply kaleidoscope\n        kaleido_frame = apply_kaleidoscope(rotated, segments=segments)\n\n        frames.append(kaleido_frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    from core.gif_builder import GIFBuilder\n\n    print(\"Creating kaleidoscope GIF...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Create kaleidoscope animation\n    frames = create_kaleidoscope_animation(\n        num_frames=40,\n        segments=8,\n        rotation_speed=0.5\n    )\n\n    builder.add_frames(frames)\n    builder.save('kaleidoscope_test.gif', num_colors=128)\n"
  },
  {
    "path": "slack-gif-creator/templates/morph.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nMorph Animation - Transform between different emojis or shapes.\n\nCreates smooth transitions and transformations.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nimport numpy as np\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced, draw_circle\nfrom core.easing import interpolate\n\n\ndef create_morph_animation(\n    object1_data: dict,\n    object2_data: dict,\n    num_frames: int = 30,\n    morph_type: str = 'crossfade',  # 'crossfade', 'scale', 'spin_morph'\n    easing: str = 'ease_in_out',\n    object_type: str = 'emoji',\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create morphing animation between two objects.\n\n    Args:\n        object1_data: First object configuration\n        object2_data: Second object configuration\n        num_frames: Number of frames\n        morph_type: Type of morph effect\n        easing: Easing function\n        object_type: Type of objects\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        if morph_type == 'crossfade':\n            # Simple crossfade between two objects\n            opacity1 = interpolate(1, 0, t, easing)\n            opacity2 = interpolate(0, 1, t, easing)\n\n            if object_type == 'emoji':\n                # Create first emoji\n                emoji1_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n                size1 = object1_data['size']\n                draw_emoji_enhanced(\n                    emoji1_canvas,\n                    emoji=object1_data['emoji'],\n                    position=(center_pos[0] - size1 // 2, center_pos[1] - size1 // 2),\n                    size=size1,\n                    shadow=False\n                )\n\n                # Apply opacity\n                from templates.fade import apply_opacity\n                emoji1_canvas = apply_opacity(emoji1_canvas, opacity1)\n\n                # Create second emoji\n                emoji2_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n                size2 = object2_data['size']\n                draw_emoji_enhanced(\n                    emoji2_canvas,\n                    emoji=object2_data['emoji'],\n                    position=(center_pos[0] - size2 // 2, center_pos[1] - size2 // 2),\n                    size=size2,\n                    shadow=False\n                )\n\n                emoji2_canvas = apply_opacity(emoji2_canvas, opacity2)\n\n                # Composite both\n                frame_rgba = frame.convert('RGBA')\n                frame_rgba = Image.alpha_composite(frame_rgba, emoji1_canvas)\n                frame_rgba = Image.alpha_composite(frame_rgba, emoji2_canvas)\n                frame = frame_rgba.convert('RGB')\n\n            elif object_type == 'circle':\n                # Morph between two circles\n                radius1 = object1_data['radius']\n                radius2 = object2_data['radius']\n                color1 = object1_data['color']\n                color2 = object2_data['color']\n\n                # Interpolate properties\n                current_radius = int(interpolate(radius1, radius2, t, easing))\n                current_color = tuple(\n                    int(interpolate(color1[i], color2[i], t, easing))\n                    for i in range(3)\n                )\n\n                draw_circle(frame, center_pos, current_radius, fill_color=current_color)\n\n        elif morph_type == 'scale':\n            # First object scales down as second scales up\n            if object_type == 'emoji':\n                scale1 = interpolate(1.0, 0.0, t, easing)\n                scale2 = interpolate(0.0, 1.0, t, easing)\n\n                # Draw first emoji (shrinking)\n                if scale1 > 0.05:\n                    size1 = int(object1_data['size'] * scale1)\n                    size1 = max(12, size1)\n                    emoji1_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n                    draw_emoji_enhanced(\n                        emoji1_canvas,\n                        emoji=object1_data['emoji'],\n                        position=(center_pos[0] - size1 // 2, center_pos[1] - size1 // 2),\n                        size=size1,\n                        shadow=False\n                    )\n\n                    frame_rgba = frame.convert('RGBA')\n                    frame = Image.alpha_composite(frame_rgba, emoji1_canvas)\n                    frame = frame.convert('RGB')\n\n                # Draw second emoji (growing)\n                if scale2 > 0.05:\n                    size2 = int(object2_data['size'] * scale2)\n                    size2 = max(12, size2)\n                    emoji2_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n                    draw_emoji_enhanced(\n                        emoji2_canvas,\n                        emoji=object2_data['emoji'],\n                        position=(center_pos[0] - size2 // 2, center_pos[1] - size2 // 2),\n                        size=size2,\n                        shadow=False\n                    )\n\n                    frame_rgba = frame.convert('RGBA')\n                    frame = Image.alpha_composite(frame_rgba, emoji2_canvas)\n                    frame = frame.convert('RGB')\n\n        elif morph_type == 'spin_morph':\n            # Spin while morphing (flip-like)\n            import math\n\n            # Calculate rotation (0 to 180 degrees)\n            angle = interpolate(0, 180, t, easing)\n            scale_factor = abs(math.cos(math.radians(angle)))\n\n            # Determine which object to show\n            if angle < 90:\n                current_object = object1_data\n            else:\n                current_object = object2_data\n\n            # Skip when edge-on\n            if scale_factor < 0.05:\n                frames.append(frame)\n                continue\n\n            if object_type == 'emoji':\n                size = current_object['size']\n                canvas_size = size * 2\n                emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n                draw_emoji_enhanced(\n                    emoji_canvas,\n                    emoji=current_object['emoji'],\n                    position=(canvas_size // 2 - size // 2, canvas_size // 2 - size // 2),\n                    size=size,\n                    shadow=False\n                )\n\n                # Scale horizontally for spin effect\n                new_width = max(1, int(canvas_size * scale_factor))\n                emoji_scaled = emoji_canvas.resize((new_width, canvas_size), Image.LANCZOS)\n\n                paste_x = center_pos[0] - new_width // 2\n                paste_y = center_pos[1] - canvas_size // 2\n\n                frame_rgba = frame.convert('RGBA')\n                frame_rgba.paste(emoji_scaled, (paste_x, paste_y), emoji_scaled)\n                frame = frame_rgba.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_reaction_morph(\n    emoji_start: str,\n    emoji_end: str,\n    num_frames: int = 20,\n    frame_size: int = 128\n) -> list[Image.Image]:\n    \"\"\"\n    Create quick emoji reaction morph (for emoji GIFs).\n\n    Args:\n        emoji_start: Starting emoji\n        emoji_end: Ending emoji\n        num_frames: Number of frames\n        frame_size: Frame size (square)\n\n    Returns:\n        List of frames\n    \"\"\"\n    return create_morph_animation(\n        object1_data={'emoji': emoji_start, 'size': 80},\n        object2_data={'emoji': emoji_end, 'size': 80},\n        num_frames=num_frames,\n        morph_type='crossfade',\n        easing='ease_in_out',\n        object_type='emoji',\n        center_pos=(frame_size // 2, frame_size // 2),\n        frame_width=frame_size,\n        frame_height=frame_size,\n        bg_color=(255, 255, 255)\n    )\n\n\ndef create_shape_morph(\n    shapes: list[dict],\n    num_frames: int = 60,\n    frames_per_shape: int = 20,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Morph through a sequence of shapes.\n\n    Args:\n        shapes: List of shape dicts with 'radius' and 'color'\n        num_frames: Total number of frames\n        frames_per_shape: Frames to spend on each morph\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n    center = (frame_width // 2, frame_height // 2)\n\n    for i in range(num_frames):\n        # Determine which shapes we're morphing between\n        cycle_progress = (i % (frames_per_shape * len(shapes))) / frames_per_shape\n        shape_idx = int(cycle_progress) % len(shapes)\n        next_shape_idx = (shape_idx + 1) % len(shapes)\n\n        # Progress between these two shapes\n        t = cycle_progress - shape_idx\n\n        shape1 = shapes[shape_idx]\n        shape2 = shapes[next_shape_idx]\n\n        # Interpolate properties\n        radius = int(interpolate(shape1['radius'], shape2['radius'], t, 'ease_in_out'))\n        color = tuple(\n            int(interpolate(shape1['color'][j], shape2['color'][j], t, 'ease_in_out'))\n            for j in range(3)\n        )\n\n        # Draw frame\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n        draw_circle(frame, center, radius, fill_color=color)\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating morph animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Crossfade morph\n    frames = create_morph_animation(\n        object1_data={'emoji': '😊', 'size': 100},\n        object2_data={'emoji': '😂', 'size': 100},\n        num_frames=30,\n        morph_type='crossfade',\n        object_type='emoji'\n    )\n    builder.add_frames(frames)\n    builder.save('morph_crossfade.gif', num_colors=128)\n\n    # Example 2: Scale morph\n    builder.clear()\n    frames = create_morph_animation(\n        object1_data={'emoji': '🌙', 'size': 100},\n        object2_data={'emoji': '☀️', 'size': 100},\n        num_frames=40,\n        morph_type='scale',\n        object_type='emoji'\n    )\n    builder.add_frames(frames)\n    builder.save('morph_scale.gif', num_colors=128)\n\n    # Example 3: Shape morph cycle\n    builder.clear()\n    from core.color_palettes import get_palette\n    palette = get_palette('vibrant')\n\n    shapes = [\n        {'radius': 60, 'color': palette['primary']},\n        {'radius': 80, 'color': palette['secondary']},\n        {'radius': 50, 'color': palette['accent']},\n        {'radius': 70, 'color': palette['success']}\n    ]\n    frames = create_shape_morph(shapes, num_frames=80, frames_per_shape=20)\n    builder.add_frames(frames)\n    builder.save('morph_shapes.gif', num_colors=64)\n\n    print(\"Created morph animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/move.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nMove Animation - Move objects along paths with various motion types.\n\nProvides flexible movement primitives for objects along linear, arc, or custom paths.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_circle, draw_emoji_enhanced\nfrom core.easing import interpolate, calculate_arc_motion\n\n\ndef create_move_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    start_pos: tuple[int, int] = (50, 240),\n    end_pos: tuple[int, int] = (430, 240),\n    num_frames: int = 30,\n    motion_type: str = 'linear',  # 'linear', 'arc', 'bezier', 'circle', 'wave'\n    easing: str = 'ease_out',\n    motion_params: dict | None = None,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list:\n    \"\"\"\n    Create frames showing object moving along a path.\n\n    Args:\n        object_type: 'circle', 'emoji', or 'custom'\n        object_data: Data for the object\n        start_pos: Starting (x, y) position\n        end_pos: Ending (x, y) position\n        num_frames: Number of frames\n        motion_type: Type of motion path\n        easing: Easing function name\n        motion_params: Additional parameters for motion (e.g., {'arc_height': 100})\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'circle':\n            object_data = {'radius': 30, 'color': (100, 150, 255)}\n        elif object_type == 'emoji':\n            object_data = {'emoji': '🚀', 'size': 60}\n\n    # Default motion params\n    if motion_params is None:\n        motion_params = {}\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate position based on motion type\n        if motion_type == 'linear':\n            # Straight line with easing\n            x = interpolate(start_pos[0], end_pos[0], t, easing)\n            y = interpolate(start_pos[1], end_pos[1], t, easing)\n\n        elif motion_type == 'arc':\n            # Parabolic arc\n            arc_height = motion_params.get('arc_height', 100)\n            x, y = calculate_arc_motion(start_pos, end_pos, arc_height, t)\n\n        elif motion_type == 'circle':\n            # Circular motion around a center\n            center = motion_params.get('center', (frame_width // 2, frame_height // 2))\n            radius = motion_params.get('radius', 150)\n            start_angle = motion_params.get('start_angle', 0)\n            angle_range = motion_params.get('angle_range', 360)  # Full circle\n\n            angle = start_angle + (angle_range * t)\n            angle_rad = math.radians(angle)\n\n            x = center[0] + radius * math.cos(angle_rad)\n            y = center[1] + radius * math.sin(angle_rad)\n\n        elif motion_type == 'wave':\n            # Move in straight line but add wave motion\n            wave_amplitude = motion_params.get('wave_amplitude', 50)\n            wave_frequency = motion_params.get('wave_frequency', 2)\n\n            # Base linear motion\n            base_x = interpolate(start_pos[0], end_pos[0], t, easing)\n            base_y = interpolate(start_pos[1], end_pos[1], t, easing)\n\n            # Add wave offset perpendicular to motion direction\n            dx = end_pos[0] - start_pos[0]\n            dy = end_pos[1] - start_pos[1]\n            length = math.sqrt(dx * dx + dy * dy)\n\n            if length > 0:\n                # Perpendicular direction\n                perp_x = -dy / length\n                perp_y = dx / length\n\n                # Wave offset\n                wave_offset = math.sin(t * wave_frequency * 2 * math.pi) * wave_amplitude\n\n                x = base_x + perp_x * wave_offset\n                y = base_y + perp_y * wave_offset\n            else:\n                x, y = base_x, base_y\n\n        elif motion_type == 'bezier':\n            # Quadratic bezier curve\n            control_point = motion_params.get('control_point', (\n                (start_pos[0] + end_pos[0]) // 2,\n                (start_pos[1] + end_pos[1]) // 2 - 100\n            ))\n\n            # Quadratic Bezier formula: B(t) = (1-t)²P0 + 2(1-t)tP1 + t²P2\n            x = (1 - t) ** 2 * start_pos[0] + 2 * (1 - t) * t * control_point[0] + t ** 2 * end_pos[0]\n            y = (1 - t) ** 2 * start_pos[1] + 2 * (1 - t) * t * control_point[1] + t ** 2 * end_pos[1]\n\n        else:\n            # Default to linear\n            x = interpolate(start_pos[0], end_pos[0], t, easing)\n            y = interpolate(start_pos[1], end_pos[1], t, easing)\n\n        # Draw object at calculated position\n        x, y = int(x), int(y)\n\n        if object_type == 'circle':\n            draw_circle(\n                frame,\n                center=(x, y),\n                radius=object_data['radius'],\n                fill_color=object_data['color']\n            )\n        elif object_type == 'emoji':\n            draw_emoji_enhanced(\n                frame,\n                emoji=object_data['emoji'],\n                position=(x - object_data['size'] // 2, y - object_data['size'] // 2),\n                size=object_data['size'],\n                shadow=object_data.get('shadow', True)\n            )\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_path_from_points(points: list[tuple[int, int]],\n                            num_frames: int = 60,\n                            easing: str = 'ease_in_out') -> list[tuple[int, int]]:\n    \"\"\"\n    Create a smooth path through multiple points.\n\n    Args:\n        points: List of (x, y) waypoints\n        num_frames: Total number of frames\n        easing: Easing between points\n\n    Returns:\n        List of (x, y) positions for each frame\n    \"\"\"\n    if len(points) < 2:\n        return points * num_frames\n\n    path = []\n    frames_per_segment = num_frames // (len(points) - 1)\n\n    for i in range(len(points) - 1):\n        start = points[i]\n        end = points[i + 1]\n\n        # Last segment gets remaining frames\n        if i == len(points) - 2:\n            segment_frames = num_frames - len(path)\n        else:\n            segment_frames = frames_per_segment\n\n        for j in range(segment_frames):\n            t = j / segment_frames if segment_frames > 0 else 0\n            x = interpolate(start[0], end[0], t, easing)\n            y = interpolate(start[1], end[1], t, easing)\n            path.append((int(x), int(y)))\n\n    return path\n\n\ndef apply_trail_effect(frames: list, trail_length: int = 5,\n                      fade_alpha: float = 0.3) -> list:\n    \"\"\"\n    Add motion trail effect to moving object.\n\n    Args:\n        frames: List of frames with moving object\n        trail_length: Number of previous frames to blend\n        fade_alpha: Opacity of trail frames\n\n    Returns:\n        List of frames with trail effect\n    \"\"\"\n    from PIL import Image, ImageChops\n    import numpy as np\n\n    trailed_frames = []\n\n    for i, frame in enumerate(frames):\n        # Start with current frame\n        result = frame.copy()\n\n        # Blend previous frames\n        for j in range(1, min(trail_length + 1, i + 1)):\n            prev_frame = frames[i - j]\n\n            # Calculate fade\n            alpha = fade_alpha ** j\n\n            # Blend\n            result_array = np.array(result, dtype=np.float32)\n            prev_array = np.array(prev_frame, dtype=np.float32)\n\n            blended = result_array * (1 - alpha) + prev_array * alpha\n            result = Image.fromarray(blended.astype(np.uint8))\n\n        trailed_frames.append(result)\n\n    return trailed_frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating movement examples...\")\n\n    # Example 1: Linear movement\n    builder = GIFBuilder(width=480, height=480, fps=20)\n    frames = create_move_animation(\n        object_type='emoji',\n        object_data={'emoji': '🚀', 'size': 60},\n        start_pos=(50, 240),\n        end_pos=(430, 240),\n        num_frames=30,\n        motion_type='linear',\n        easing='ease_out'\n    )\n    builder.add_frames(frames)\n    builder.save('move_linear.gif', num_colors=128)\n\n    # Example 2: Arc movement\n    builder.clear()\n    frames = create_move_animation(\n        object_type='emoji',\n        object_data={'emoji': '⚽', 'size': 60},\n        start_pos=(50, 350),\n        end_pos=(430, 350),\n        num_frames=30,\n        motion_type='arc',\n        motion_params={'arc_height': 150},\n        easing='linear'\n    )\n    builder.add_frames(frames)\n    builder.save('move_arc.gif', num_colors=128)\n\n    # Example 3: Circular movement\n    builder.clear()\n    frames = create_move_animation(\n        object_type='emoji',\n        object_data={'emoji': '🌍', 'size': 50},\n        start_pos=(0, 0),  # Ignored for circle\n        end_pos=(0, 0),    # Ignored for circle\n        num_frames=40,\n        motion_type='circle',\n        motion_params={\n            'center': (240, 240),\n            'radius': 120,\n            'start_angle': 0,\n            'angle_range': 360\n        },\n        easing='linear'\n    )\n    builder.add_frames(frames)\n    builder.save('move_circle.gif', num_colors=128)\n\n    print(\"Created movement examples!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/pulse.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nPulse Animation - Scale objects rhythmically for emphasis.\n\nCreates pulsing, heartbeat, and throbbing effects.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced, draw_circle\nfrom core.easing import interpolate\n\n\ndef create_pulse_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    pulse_type: str = 'smooth',  # 'smooth', 'heartbeat', 'throb', 'pop'\n    scale_range: tuple[float, float] = (0.8, 1.2),\n    pulses: float = 2.0,\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create pulsing/scaling animation.\n\n    Args:\n        object_type: 'emoji', 'circle', 'text'\n        object_data: Object configuration\n        num_frames: Number of frames\n        pulse_type: Type of pulsing motion\n        scale_range: (min_scale, max_scale) tuple\n        pulses: Number of pulses in animation\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '❤️', 'size': 100}\n        elif object_type == 'circle':\n            object_data = {'radius': 50, 'color': (255, 100, 100)}\n\n    min_scale, max_scale = scale_range\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate scale based on pulse type\n        if pulse_type == 'smooth':\n            # Simple sinusoidal pulse\n            scale = min_scale + (max_scale - min_scale) * (\n                0.5 + 0.5 * math.sin(t * pulses * 2 * math.pi - math.pi / 2)\n            )\n\n        elif pulse_type == 'heartbeat':\n            # Double pump like a heartbeat\n            phase = (t * pulses) % 1.0\n            if phase < 0.15:\n                # First pump\n                scale = interpolate(min_scale, max_scale, phase / 0.15, 'ease_out')\n            elif phase < 0.25:\n                # First release\n                scale = interpolate(max_scale, min_scale, (phase - 0.15) / 0.10, 'ease_in')\n            elif phase < 0.35:\n                # Second pump (smaller)\n                scale = interpolate(min_scale, (min_scale + max_scale) / 2, (phase - 0.25) / 0.10, 'ease_out')\n            elif phase < 0.45:\n                # Second release\n                scale = interpolate((min_scale + max_scale) / 2, min_scale, (phase - 0.35) / 0.10, 'ease_in')\n            else:\n                # Rest period\n                scale = min_scale\n\n        elif pulse_type == 'throb':\n            # Sharp pulse with quick return\n            phase = (t * pulses) % 1.0\n            if phase < 0.2:\n                scale = interpolate(min_scale, max_scale, phase / 0.2, 'ease_out')\n            else:\n                scale = interpolate(max_scale, min_scale, (phase - 0.2) / 0.8, 'ease_in')\n\n        elif pulse_type == 'pop':\n            # Pop out and back with overshoot\n            phase = (t * pulses) % 1.0\n            if phase < 0.3:\n                # Pop out with overshoot\n                scale = interpolate(min_scale, max_scale * 1.1, phase / 0.3, 'elastic_out')\n            else:\n                # Settle back\n                scale = interpolate(max_scale * 1.1, min_scale, (phase - 0.3) / 0.7, 'ease_out')\n\n        else:\n            scale = min_scale + (max_scale - min_scale) * (\n                0.5 + 0.5 * math.sin(t * pulses * 2 * math.pi)\n            )\n\n        # Draw object at calculated scale\n        if object_type == 'emoji':\n            base_size = object_data['size']\n            current_size = int(base_size * scale)\n            draw_emoji_enhanced(\n                frame,\n                emoji=object_data['emoji'],\n                position=(center_pos[0] - current_size // 2, center_pos[1] - current_size // 2),\n                size=current_size,\n                shadow=object_data.get('shadow', True)\n            )\n\n        elif object_type == 'circle':\n            base_radius = object_data['radius']\n            current_radius = int(base_radius * scale)\n            draw_circle(\n                frame,\n                center=center_pos,\n                radius=current_radius,\n                fill_color=object_data['color']\n            )\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n            base_size = object_data.get('font_size', 50)\n            current_size = int(base_size * scale)\n            draw_text_with_outline(\n                frame,\n                text=object_data.get('text', 'PULSE'),\n                position=center_pos,\n                font_size=current_size,\n                text_color=object_data.get('text_color', (255, 100, 100)),\n                outline_color=object_data.get('outline_color', (0, 0, 0)),\n                outline_width=3,\n                centered=True\n            )\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_attention_pulse(\n    emoji: str = '⚠️',\n    num_frames: int = 20,\n    frame_size: int = 128,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create attention-grabbing pulse (good for emoji GIFs).\n\n    Args:\n        emoji: Emoji to pulse\n        num_frames: Number of frames\n        frame_size: Frame size (square)\n        bg_color: Background color\n\n    Returns:\n        List of frames optimized for emoji size\n    \"\"\"\n    return create_pulse_animation(\n        object_type='emoji',\n        object_data={'emoji': emoji, 'size': 80, 'shadow': False},\n        num_frames=num_frames,\n        pulse_type='throb',\n        scale_range=(0.85, 1.15),\n        pulses=2,\n        center_pos=(frame_size // 2, frame_size // 2),\n        frame_width=frame_size,\n        frame_height=frame_size,\n        bg_color=bg_color\n    )\n\n\ndef create_breathing_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 60,\n    breaths: float = 2.0,\n    scale_range: tuple[float, float] = (0.9, 1.1),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (240, 248, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create slow, calming breathing animation (in and out).\n\n    Args:\n        object_type: Type of object\n        object_data: Object configuration\n        num_frames: Number of frames\n        breaths: Number of breathing cycles\n        scale_range: Min/max scale\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    if object_data is None:\n        object_data = {'emoji': '😌', 'size': 100}\n\n    return create_pulse_animation(\n        object_type=object_type,\n        object_data=object_data,\n        num_frames=num_frames,\n        pulse_type='smooth',\n        scale_range=scale_range,\n        pulses=breaths,\n        center_pos=(frame_width // 2, frame_height // 2),\n        frame_width=frame_width,\n        frame_height=frame_height,\n        bg_color=bg_color\n    )\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating pulse animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Smooth pulse\n    frames = create_pulse_animation(\n        object_type='emoji',\n        object_data={'emoji': '❤️', 'size': 100},\n        num_frames=40,\n        pulse_type='smooth',\n        scale_range=(0.8, 1.2),\n        pulses=2\n    )\n    builder.add_frames(frames)\n    builder.save('pulse_smooth.gif', num_colors=128)\n\n    # Example 2: Heartbeat\n    builder.clear()\n    frames = create_pulse_animation(\n        object_type='emoji',\n        object_data={'emoji': '💓', 'size': 100},\n        num_frames=60,\n        pulse_type='heartbeat',\n        scale_range=(0.85, 1.2),\n        pulses=3\n    )\n    builder.add_frames(frames)\n    builder.save('pulse_heartbeat.gif', num_colors=128)\n\n    # Example 3: Attention pulse (emoji size)\n    builder = GIFBuilder(width=128, height=128, fps=15)\n    frames = create_attention_pulse(emoji='⚠️', num_frames=20)\n    builder.add_frames(frames)\n    builder.save('pulse_attention.gif', num_colors=48, optimize_for_emoji=True)\n\n    print(\"Created pulse animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/shake.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nShake Animation Template - Creates shaking/vibrating motion.\n\nUse this for impact effects, emphasis, or nervous/excited reactions.\n\"\"\"\n\nimport sys\nimport math\nfrom pathlib import Path\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_circle, draw_emoji, draw_text\nfrom core.easing import ease_out_quad\n\n\ndef create_shake_animation(\n    object_type: str = 'emoji',\n    object_data: dict = None,\n    num_frames: int = 20,\n    shake_intensity: int = 15,\n    center_x: int = 240,\n    center_y: int = 240,\n    direction: str = 'horizontal',  # 'horizontal', 'vertical', or 'both'\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list:\n    \"\"\"\n    Create frames for a shaking animation.\n\n    Args:\n        object_type: 'circle', 'emoji', 'text', or 'custom'\n        object_data: Data for the object\n        num_frames: Number of frames\n        shake_intensity: Maximum shake displacement in pixels\n        center_x: Center X position\n        center_y: Center Y position\n        direction: 'horizontal', 'vertical', or 'both'\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '😱', 'size': 80}\n        elif object_type == 'text':\n            object_data = {'text': 'SHAKE!', 'font_size': 50, 'color': (255, 0, 0)}\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Calculate progress\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Decay shake intensity over time\n        intensity = shake_intensity * (1 - ease_out_quad(t))\n\n        # Calculate shake offset using sine wave for smooth oscillation\n        freq = 3  # Oscillation frequency\n        offset_x = 0\n        offset_y = 0\n\n        if direction in ['horizontal', 'both']:\n            offset_x = int(math.sin(t * freq * 2 * math.pi) * intensity)\n\n        if direction in ['vertical', 'both']:\n            offset_y = int(math.cos(t * freq * 2 * math.pi) * intensity)\n\n        # Apply offset\n        x = center_x + offset_x\n        y = center_y + offset_y\n\n        # Draw object\n        if object_type == 'emoji':\n            draw_emoji(\n                frame,\n                emoji=object_data['emoji'],\n                position=(x - object_data['size'] // 2, y - object_data['size'] // 2),\n                size=object_data['size']\n            )\n        elif object_type == 'text':\n            draw_text(\n                frame,\n                text=object_data['text'],\n                position=(x, y),\n                font_size=object_data['font_size'],\n                color=object_data['color'],\n                centered=True\n            )\n        elif object_type == 'circle':\n            draw_circle(\n                frame,\n                center=(x, y),\n                radius=object_data.get('radius', 30),\n                fill_color=object_data.get('color', (100, 100, 255))\n            )\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating shake GIF...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=24)\n\n    frames = create_shake_animation(\n        object_type='emoji',\n        object_data={'emoji': '😱', 'size': 100},\n        num_frames=30,\n        shake_intensity=20,\n        direction='both'\n    )\n\n    builder.add_frames(frames)\n    builder.save('shake_test.gif', num_colors=128)"
  },
  {
    "path": "slack-gif-creator/templates/slide.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nSlide Animation - Slide elements in from edges with overshoot/bounce.\n\nCreates smooth entrance and exit animations.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.easing import interpolate\n\n\ndef create_slide_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    direction: str = 'left',  # 'left', 'right', 'top', 'bottom'\n    slide_type: str = 'in',  # 'in', 'out', 'across'\n    easing: str = 'ease_out',\n    overshoot: bool = False,\n    final_pos: tuple[int, int] | None = None,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create slide animation.\n\n    Args:\n        object_type: 'emoji', 'text'\n        object_data: Object configuration\n        num_frames: Number of frames\n        direction: Direction of slide\n        slide_type: Type of slide (in/out/across)\n        easing: Easing function\n        overshoot: Add overshoot/bounce at end\n        final_pos: Final position (None = center)\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '➡️', 'size': 100}\n\n    if final_pos is None:\n        final_pos = (frame_width // 2, frame_height // 2)\n\n    # Calculate start and end positions based on direction\n    size = object_data.get('size', 100) if object_type == 'emoji' else 100\n    margin = size\n\n    if direction == 'left':\n        start_pos = (-margin, final_pos[1])\n        end_pos = final_pos if slide_type == 'in' else (frame_width + margin, final_pos[1])\n    elif direction == 'right':\n        start_pos = (frame_width + margin, final_pos[1])\n        end_pos = final_pos if slide_type == 'in' else (-margin, final_pos[1])\n    elif direction == 'top':\n        start_pos = (final_pos[0], -margin)\n        end_pos = final_pos if slide_type == 'in' else (final_pos[0], frame_height + margin)\n    elif direction == 'bottom':\n        start_pos = (final_pos[0], frame_height + margin)\n        end_pos = final_pos if slide_type == 'in' else (final_pos[0], -margin)\n    else:\n        start_pos = (-margin, final_pos[1])\n        end_pos = final_pos\n\n    # For 'out' type, swap start and end\n    if slide_type == 'out':\n        start_pos, end_pos = final_pos, end_pos\n    elif slide_type == 'across':\n        # Slide all the way across\n        if direction == 'left':\n            start_pos = (-margin, final_pos[1])\n            end_pos = (frame_width + margin, final_pos[1])\n        elif direction == 'right':\n            start_pos = (frame_width + margin, final_pos[1])\n            end_pos = (-margin, final_pos[1])\n        elif direction == 'top':\n            start_pos = (final_pos[0], -margin)\n            end_pos = (final_pos[0], frame_height + margin)\n        elif direction == 'bottom':\n            start_pos = (final_pos[0], frame_height + margin)\n            end_pos = (final_pos[0], -margin)\n\n    # Use overshoot easing if requested\n    if overshoot and slide_type == 'in':\n        easing = 'back_out'\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Calculate current position\n        x = int(interpolate(start_pos[0], end_pos[0], t, easing))\n        y = int(interpolate(start_pos[1], end_pos[1], t, easing))\n\n        # Draw object\n        if object_type == 'emoji':\n            size = object_data['size']\n            draw_emoji_enhanced(\n                frame,\n                emoji=object_data['emoji'],\n                position=(x - size // 2, y - size // 2),\n                size=size,\n                shadow=object_data.get('shadow', True)\n            )\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n            draw_text_with_outline(\n                frame,\n                text=object_data.get('text', 'SLIDE'),\n                position=(x, y),\n                font_size=object_data.get('font_size', 50),\n                text_color=object_data.get('text_color', (0, 0, 0)),\n                outline_color=object_data.get('outline_color', (255, 255, 255)),\n                outline_width=3,\n                centered=True\n            )\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_multi_slide(\n    objects: list[dict],\n    num_frames: int = 30,\n    stagger_delay: int = 3,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create animation with multiple objects sliding in sequence.\n\n    Args:\n        objects: List of object configs with 'type', 'data', 'direction', 'final_pos'\n        num_frames: Number of frames\n        stagger_delay: Frames between each object starting\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        for idx, obj in enumerate(objects):\n            # Calculate when this object starts moving\n            start_frame = idx * stagger_delay\n            if i < start_frame:\n                continue  # Object hasn't started yet\n\n            # Calculate progress for this object\n            obj_frame = i - start_frame\n            obj_duration = num_frames - start_frame\n            if obj_duration <= 0:\n                continue\n\n            t = obj_frame / obj_duration\n\n            # Get object properties\n            obj_type = obj.get('type', 'emoji')\n            obj_data = obj.get('data', {'emoji': '➡️', 'size': 80})\n            direction = obj.get('direction', 'left')\n            final_pos = obj.get('final_pos', (frame_width // 2, frame_height // 2))\n            easing = obj.get('easing', 'back_out')\n\n            # Calculate position\n            size = obj_data.get('size', 80)\n            margin = size\n\n            if direction == 'left':\n                start_x = -margin\n                end_x = final_pos[0]\n                y = final_pos[1]\n            elif direction == 'right':\n                start_x = frame_width + margin\n                end_x = final_pos[0]\n                y = final_pos[1]\n            elif direction == 'top':\n                x = final_pos[0]\n                start_y = -margin\n                end_y = final_pos[1]\n            elif direction == 'bottom':\n                x = final_pos[0]\n                start_y = frame_height + margin\n                end_y = final_pos[1]\n            else:\n                start_x = -margin\n                end_x = final_pos[0]\n                y = final_pos[1]\n\n            # Interpolate position\n            if direction in ['left', 'right']:\n                x = int(interpolate(start_x, end_x, t, easing))\n            else:\n                y = int(interpolate(start_y, end_y, t, easing))\n\n            # Draw object\n            if obj_type == 'emoji':\n                draw_emoji_enhanced(\n                    frame,\n                    emoji=obj_data['emoji'],\n                    position=(x - size // 2, y - size // 2),\n                    size=size,\n                    shadow=False\n                )\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating slide animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Slide in from left with overshoot\n    frames = create_slide_animation(\n        object_type='emoji',\n        object_data={'emoji': '➡️', 'size': 100},\n        num_frames=30,\n        direction='left',\n        slide_type='in',\n        overshoot=True\n    )\n    builder.add_frames(frames)\n    builder.save('slide_in_left.gif', num_colors=128)\n\n    # Example 2: Slide across\n    builder.clear()\n    frames = create_slide_animation(\n        object_type='emoji',\n        object_data={'emoji': '🚀', 'size': 80},\n        num_frames=40,\n        direction='left',\n        slide_type='across',\n        easing='ease_in_out'\n    )\n    builder.add_frames(frames)\n    builder.save('slide_across.gif', num_colors=128)\n\n    # Example 3: Multiple objects sliding in\n    builder.clear()\n    objects = [\n        {\n            'type': 'emoji',\n            'data': {'emoji': '🎯', 'size': 60},\n            'direction': 'left',\n            'final_pos': (120, 240)\n        },\n        {\n            'type': 'emoji',\n            'data': {'emoji': '🎪', 'size': 60},\n            'direction': 'right',\n            'final_pos': (240, 240)\n        },\n        {\n            'type': 'emoji',\n            'data': {'emoji': '🎨', 'size': 60},\n            'direction': 'top',\n            'final_pos': (360, 240)\n        }\n    ]\n    frames = create_multi_slide(objects, num_frames=50, stagger_delay=5)\n    builder.add_frames(frames)\n    builder.save('slide_multi.gif', num_colors=128)\n\n    print(\"Created slide animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/spin.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nSpin Animation - Rotate objects continuously or with variation.\n\nCreates spinning, rotating, and wobbling effects.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced, draw_circle\nfrom core.easing import interpolate\n\n\ndef create_spin_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    rotation_type: str = 'clockwise',  # 'clockwise', 'counterclockwise', 'wobble', 'pendulum'\n    full_rotations: float = 1.0,\n    easing: str = 'linear',\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create spinning/rotating animation.\n\n    Args:\n        object_type: 'emoji', 'image', 'text'\n        object_data: Object configuration\n        num_frames: Number of frames\n        rotation_type: Type of rotation\n        full_rotations: Number of complete 360° rotations\n        easing: Easing function for rotation speed\n        center_pos: Center position for rotation\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '🔄', 'size': 100}\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate rotation angle\n        if rotation_type == 'clockwise':\n            angle = interpolate(0, 360 * full_rotations, t, easing)\n        elif rotation_type == 'counterclockwise':\n            angle = interpolate(0, -360 * full_rotations, t, easing)\n        elif rotation_type == 'wobble':\n            # Back and forth rotation\n            angle = math.sin(t * full_rotations * 2 * math.pi) * 45\n        elif rotation_type == 'pendulum':\n            # Smooth pendulum swing\n            angle = math.sin(t * full_rotations * 2 * math.pi) * 90\n        else:\n            angle = interpolate(0, 360 * full_rotations, t, easing)\n\n        # Create object on transparent background to rotate\n        if object_type == 'emoji':\n            # For emoji, we need to create a larger canvas to avoid clipping during rotation\n            emoji_size = object_data['size']\n            canvas_size = int(emoji_size * 1.5)\n            emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            # Draw emoji in center of canvas\n            from core.frame_composer import draw_emoji_enhanced\n            draw_emoji_enhanced(\n                emoji_canvas,\n                emoji=object_data['emoji'],\n                position=(canvas_size // 2 - emoji_size // 2, canvas_size // 2 - emoji_size // 2),\n                size=emoji_size,\n                shadow=False\n            )\n\n            # Rotate the canvas\n            rotated = emoji_canvas.rotate(angle, resample=Image.BICUBIC, expand=False)\n\n            # Paste onto frame\n            paste_x = center_pos[0] - canvas_size // 2\n            paste_y = center_pos[1] - canvas_size // 2\n            frame.paste(rotated, (paste_x, paste_y), rotated)\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n            # Similar approach - create canvas, draw text, rotate\n            text = object_data.get('text', 'SPIN!')\n            font_size = object_data.get('font_size', 50)\n\n            canvas_size = max(frame_width, frame_height)\n            text_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            # Draw text\n            text_canvas_rgb = text_canvas.convert('RGB')\n            text_canvas_rgb.paste(bg_color, (0, 0, canvas_size, canvas_size))\n            draw_text_with_outline(\n                text_canvas_rgb,\n                text,\n                position=(canvas_size // 2, canvas_size // 2),\n                font_size=font_size,\n                text_color=object_data.get('text_color', (0, 0, 0)),\n                outline_color=object_data.get('outline_color', (255, 255, 255)),\n                outline_width=3,\n                centered=True\n            )\n\n            # Convert back to RGBA for rotation\n            text_canvas = text_canvas_rgb.convert('RGBA')\n\n            # Make background transparent\n            data = text_canvas.getdata()\n            new_data = []\n            for item in data:\n                if item[:3] == bg_color:\n                    new_data.append((255, 255, 255, 0))\n                else:\n                    new_data.append(item)\n            text_canvas.putdata(new_data)\n\n            # Rotate\n            rotated = text_canvas.rotate(angle, resample=Image.BICUBIC, expand=False)\n\n            # Composite onto frame\n            frame_rgba = frame.convert('RGBA')\n            frame_rgba = Image.alpha_composite(frame_rgba, rotated)\n            frame = frame_rgba.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_loading_spinner(\n    num_frames: int = 20,\n    spinner_type: str = 'dots',  # 'dots', 'arc', 'emoji'\n    size: int = 100,\n    color: tuple[int, int, int] = (100, 150, 255),\n    frame_width: int = 128,\n    frame_height: int = 128,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create a loading spinner animation.\n\n    Args:\n        num_frames: Number of frames\n        spinner_type: Type of spinner\n        size: Spinner size\n        color: Spinner color\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    from PIL import ImageDraw\n    frames = []\n    center = (frame_width // 2, frame_height // 2)\n\n    for i in range(num_frames):\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n        draw = ImageDraw.Draw(frame)\n\n        angle_offset = (i / num_frames) * 360\n\n        if spinner_type == 'dots':\n            # Circular dots\n            num_dots = 8\n            for j in range(num_dots):\n                angle = (j / num_dots * 360 + angle_offset) * math.pi / 180\n                x = center[0] + size * 0.4 * math.cos(angle)\n                y = center[1] + size * 0.4 * math.sin(angle)\n\n                # Fade based on position\n                alpha = 1.0 - (j / num_dots)\n                dot_color = tuple(int(c * alpha) for c in color)\n                dot_radius = int(size * 0.1)\n\n                draw.ellipse(\n                    [x - dot_radius, y - dot_radius, x + dot_radius, y + dot_radius],\n                    fill=dot_color\n                )\n\n        elif spinner_type == 'arc':\n            # Rotating arc\n            start_angle = angle_offset\n            end_angle = angle_offset + 270\n            arc_width = int(size * 0.15)\n\n            bbox = [\n                center[0] - size // 2,\n                center[1] - size // 2,\n                center[0] + size // 2,\n                center[1] + size // 2\n            ]\n            draw.arc(bbox, start_angle, end_angle, fill=color, width=arc_width)\n\n        elif spinner_type == 'emoji':\n            # Rotating emoji spinner\n            angle = angle_offset\n            emoji_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n            draw_emoji_enhanced(\n                emoji_canvas,\n                emoji='⏳',\n                position=(center[0] - size // 2, center[1] - size // 2),\n                size=size,\n                shadow=False\n            )\n            rotated = emoji_canvas.rotate(angle, center=center, resample=Image.BICUBIC)\n            frame.paste(rotated, (0, 0), rotated)\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating spin animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Clockwise spin\n    frames = create_spin_animation(\n        object_type='emoji',\n        object_data={'emoji': '🔄', 'size': 100},\n        num_frames=30,\n        rotation_type='clockwise',\n        full_rotations=2\n    )\n    builder.add_frames(frames)\n    builder.save('spin_clockwise.gif', num_colors=128)\n\n    # Example 2: Wobble\n    builder.clear()\n    frames = create_spin_animation(\n        object_type='emoji',\n        object_data={'emoji': '🎯', 'size': 100},\n        num_frames=30,\n        rotation_type='wobble',\n        full_rotations=3\n    )\n    builder.add_frames(frames)\n    builder.save('spin_wobble.gif', num_colors=128)\n\n    # Example 3: Loading spinner\n    builder = GIFBuilder(width=128, height=128, fps=15)\n    frames = create_loading_spinner(num_frames=20, spinner_type='dots')\n    builder.add_frames(frames)\n    builder.save('loading_spinner.gif', num_colors=64, optimize_for_emoji=True)\n\n    print(\"Created spin animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/wiggle.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nWiggle Animation - Smooth, organic wobbling and jiggling motions.\n\nCreates playful, elastic movements that are smoother than shake.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.easing import interpolate\n\n\ndef create_wiggle_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    wiggle_type: str = 'jello',  # 'jello', 'wave', 'bounce', 'sway'\n    intensity: float = 1.0,\n    cycles: float = 2.0,\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create wiggle/wobble animation.\n\n    Args:\n        object_type: 'emoji', 'text'\n        object_data: Object configuration\n        num_frames: Number of frames\n        wiggle_type: Type of wiggle motion\n        intensity: Wiggle intensity multiplier\n        cycles: Number of wiggle cycles\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '🎈', 'size': 100}\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        # Calculate wiggle transformations\n        offset_x = 0\n        offset_y = 0\n        rotation = 0\n        scale_x = 1.0\n        scale_y = 1.0\n\n        if wiggle_type == 'jello':\n            # Jello wobble - multiple frequencies\n            freq1 = cycles * 2 * math.pi\n            freq2 = cycles * 3 * math.pi\n            freq3 = cycles * 5 * math.pi\n\n            decay = 1.0 - t if cycles < 1.5 else 1.0  # Decay for single wiggles\n\n            offset_x = (\n                math.sin(freq1 * t) * 15 +\n                math.sin(freq2 * t) * 8 +\n                math.sin(freq3 * t) * 3\n            ) * intensity * decay\n\n            rotation = (\n                math.sin(freq1 * t) * 10 +\n                math.cos(freq2 * t) * 5\n            ) * intensity * decay\n\n            # Squash and stretch\n            scale_y = 1.0 + math.sin(freq1 * t) * 0.1 * intensity * decay\n            scale_x = 1.0 / scale_y  # Preserve volume\n\n        elif wiggle_type == 'wave':\n            # Wave motion\n            freq = cycles * 2 * math.pi\n            offset_y = math.sin(freq * t) * 20 * intensity\n            rotation = math.sin(freq * t + math.pi / 4) * 8 * intensity\n\n        elif wiggle_type == 'bounce':\n            # Bouncy wiggle\n            freq = cycles * 2 * math.pi\n            bounce = abs(math.sin(freq * t))\n\n            scale_y = 1.0 + bounce * 0.2 * intensity\n            scale_x = 1.0 - bounce * 0.1 * intensity\n            offset_y = -bounce * 10 * intensity\n\n        elif wiggle_type == 'sway':\n            # Gentle sway back and forth\n            freq = cycles * 2 * math.pi\n            offset_x = math.sin(freq * t) * 25 * intensity\n            rotation = math.sin(freq * t) * 12 * intensity\n\n            # Subtle scale change\n            scale = 1.0 + math.sin(freq * t) * 0.05 * intensity\n            scale_x = scale\n            scale_y = scale\n\n        elif wiggle_type == 'tail_wag':\n            # Like a wagging tail - base stays, tip moves\n            freq = cycles * 2 * math.pi\n            wag = math.sin(freq * t) * intensity\n\n            # Rotation focused at one end\n            rotation = wag * 20\n            offset_x = wag * 15\n\n        # Apply transformations\n        if object_type == 'emoji':\n            size = object_data['size']\n            size_x = int(size * scale_x)\n            size_y = int(size * scale_y)\n\n            # For non-uniform scaling or rotation, we need to use PIL transforms\n            if abs(scale_x - scale_y) > 0.01 or abs(rotation) > 0.1:\n                # Create emoji on transparent canvas\n                canvas_size = int(size * 2)\n                emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n                # Draw emoji\n                draw_emoji_enhanced(\n                    emoji_canvas,\n                    emoji=object_data['emoji'],\n                    position=(canvas_size // 2 - size // 2, canvas_size // 2 - size // 2),\n                    size=size,\n                    shadow=False\n                )\n\n                # Scale\n                if abs(scale_x - scale_y) > 0.01:\n                    new_size = (int(canvas_size * scale_x), int(canvas_size * scale_y))\n                    emoji_canvas = emoji_canvas.resize(new_size, Image.LANCZOS)\n                    canvas_size_x, canvas_size_y = new_size\n                else:\n                    canvas_size_x = canvas_size_y = canvas_size\n\n                # Rotate\n                if abs(rotation) > 0.1:\n                    emoji_canvas = emoji_canvas.rotate(\n                        rotation,\n                        resample=Image.BICUBIC,\n                        expand=False\n                    )\n\n                # Position with offset\n                paste_x = int(center_pos[0] - canvas_size_x // 2 + offset_x)\n                paste_y = int(center_pos[1] - canvas_size_y // 2 + offset_y)\n\n                frame_rgba = frame.convert('RGBA')\n                frame_rgba.paste(emoji_canvas, (paste_x, paste_y), emoji_canvas)\n                frame = frame_rgba.convert('RGB')\n            else:\n                # Simple case - just offset\n                pos_x = int(center_pos[0] - size // 2 + offset_x)\n                pos_y = int(center_pos[1] - size // 2 + offset_y)\n                draw_emoji_enhanced(\n                    frame,\n                    emoji=object_data['emoji'],\n                    position=(pos_x, pos_y),\n                    size=size,\n                    shadow=object_data.get('shadow', True)\n                )\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n\n            # Create text on canvas for transformation\n            canvas_size = max(frame_width, frame_height)\n            text_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            # Convert to RGB for drawing\n            text_canvas_rgb = text_canvas.convert('RGB')\n            text_canvas_rgb.paste(bg_color, (0, 0, canvas_size, canvas_size))\n\n            draw_text_with_outline(\n                text_canvas_rgb,\n                text=object_data.get('text', 'WIGGLE'),\n                position=(canvas_size // 2, canvas_size // 2),\n                font_size=object_data.get('font_size', 50),\n                text_color=object_data.get('text_color', (0, 0, 0)),\n                outline_color=object_data.get('outline_color', (255, 255, 255)),\n                outline_width=3,\n                centered=True\n            )\n\n            # Make transparent\n            text_canvas = text_canvas_rgb.convert('RGBA')\n            data = text_canvas.getdata()\n            new_data = []\n            for item in data:\n                if item[:3] == bg_color:\n                    new_data.append((255, 255, 255, 0))\n                else:\n                    new_data.append(item)\n            text_canvas.putdata(new_data)\n\n            # Apply rotation\n            if abs(rotation) > 0.1:\n                text_canvas = text_canvas.rotate(rotation, center=(canvas_size // 2, canvas_size // 2), resample=Image.BICUBIC)\n\n            # Crop to frame with offset\n            left = (canvas_size - frame_width) // 2 - int(offset_x)\n            top = (canvas_size - frame_height) // 2 - int(offset_y)\n            text_cropped = text_canvas.crop((left, top, left + frame_width, top + frame_height))\n\n            frame_rgba = frame.convert('RGBA')\n            frame = Image.alpha_composite(frame_rgba, text_cropped)\n            frame = frame.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_excited_wiggle(\n    emoji: str = '🎉',\n    num_frames: int = 20,\n    frame_size: int = 128\n) -> list[Image.Image]:\n    \"\"\"\n    Create excited wiggle for emoji GIFs.\n\n    Args:\n        emoji: Emoji to wiggle\n        num_frames: Number of frames\n        frame_size: Frame size (square)\n\n    Returns:\n        List of frames\n    \"\"\"\n    return create_wiggle_animation(\n        object_type='emoji',\n        object_data={'emoji': emoji, 'size': 80, 'shadow': False},\n        num_frames=num_frames,\n        wiggle_type='jello',\n        intensity=0.8,\n        cycles=2,\n        center_pos=(frame_size // 2, frame_size // 2),\n        frame_width=frame_size,\n        frame_height=frame_size,\n        bg_color=(255, 255, 255)\n    )\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating wiggle animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Jello wiggle\n    frames = create_wiggle_animation(\n        object_type='emoji',\n        object_data={'emoji': '🎈', 'size': 100},\n        num_frames=40,\n        wiggle_type='jello',\n        intensity=1.0,\n        cycles=2\n    )\n    builder.add_frames(frames)\n    builder.save('wiggle_jello.gif', num_colors=128)\n\n    # Example 2: Wave\n    builder.clear()\n    frames = create_wiggle_animation(\n        object_type='emoji',\n        object_data={'emoji': '🌊', 'size': 100},\n        num_frames=30,\n        wiggle_type='wave',\n        intensity=1.2,\n        cycles=3\n    )\n    builder.add_frames(frames)\n    builder.save('wiggle_wave.gif', num_colors=128)\n\n    # Example 3: Excited wiggle (emoji size)\n    builder = GIFBuilder(width=128, height=128, fps=15)\n    frames = create_excited_wiggle(emoji='🎉', num_frames=20)\n    builder.add_frames(frames)\n    builder.save('wiggle_excited.gif', num_colors=48, optimize_for_emoji=True)\n\n    print(\"Created wiggle animations!\")\n"
  },
  {
    "path": "slack-gif-creator/templates/zoom.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nZoom Animation - Scale objects dramatically for emphasis.\n\nCreates zoom in, zoom out, and dramatic scaling effects.\n\"\"\"\n\nimport sys\nfrom pathlib import Path\nimport math\n\nsys.path.append(str(Path(__file__).parent.parent))\n\nfrom PIL import Image, ImageFilter\nfrom core.gif_builder import GIFBuilder\nfrom core.frame_composer import create_blank_frame, draw_emoji_enhanced\nfrom core.easing import interpolate\n\n\ndef create_zoom_animation(\n    object_type: str = 'emoji',\n    object_data: dict | None = None,\n    num_frames: int = 30,\n    zoom_type: str = 'in',  # 'in', 'out', 'in_out', 'punch'\n    scale_range: tuple[float, float] = (0.1, 2.0),\n    easing: str = 'ease_out',\n    add_motion_blur: bool = False,\n    center_pos: tuple[int, int] = (240, 240),\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create zoom animation.\n\n    Args:\n        object_type: 'emoji', 'text', 'image'\n        object_data: Object configuration\n        num_frames: Number of frames\n        zoom_type: Type of zoom effect\n        scale_range: (start_scale, end_scale) tuple\n        easing: Easing function\n        add_motion_blur: Add blur for speed effect\n        center_pos: Center position\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    # Default object data\n    if object_data is None:\n        if object_type == 'emoji':\n            object_data = {'emoji': '🔍', 'size': 100}\n\n    base_size = object_data.get('size', 100) if object_type == 'emoji' else object_data.get('font_size', 60)\n    start_scale, end_scale = scale_range\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Calculate scale based on zoom type\n        if zoom_type == 'in':\n            scale = interpolate(start_scale, end_scale, t, easing)\n        elif zoom_type == 'out':\n            scale = interpolate(end_scale, start_scale, t, easing)\n        elif zoom_type == 'in_out':\n            if t < 0.5:\n                scale = interpolate(start_scale, end_scale, t * 2, easing)\n            else:\n                scale = interpolate(end_scale, start_scale, (t - 0.5) * 2, easing)\n        elif zoom_type == 'punch':\n            # Quick zoom in with overshoot then settle\n            if t < 0.3:\n                scale = interpolate(start_scale, end_scale * 1.2, t / 0.3, 'ease_out')\n            else:\n                scale = interpolate(end_scale * 1.2, end_scale, (t - 0.3) / 0.7, 'elastic_out')\n        else:\n            scale = interpolate(start_scale, end_scale, t, easing)\n\n        # Create frame\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        if object_type == 'emoji':\n            current_size = int(base_size * scale)\n\n            # Clamp size to reasonable bounds\n            current_size = max(12, min(current_size, frame_width * 2))\n\n            # Create emoji on transparent background\n            canvas_size = max(frame_width, frame_height, current_size) * 2\n            emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n            draw_emoji_enhanced(\n                emoji_canvas,\n                emoji=object_data['emoji'],\n                position=(canvas_size // 2 - current_size // 2, canvas_size // 2 - current_size // 2),\n                size=current_size,\n                shadow=False\n            )\n\n            # Optional motion blur for fast zooms\n            if add_motion_blur and abs(scale - 1.0) > 0.5:\n                blur_amount = min(5, int(abs(scale - 1.0) * 3))\n                emoji_canvas = emoji_canvas.filter(ImageFilter.GaussianBlur(blur_amount))\n\n            # Crop to frame size centered\n            left = (canvas_size - frame_width) // 2\n            top = (canvas_size - frame_height) // 2\n            emoji_cropped = emoji_canvas.crop((left, top, left + frame_width, top + frame_height))\n\n            # Composite\n            frame_rgba = frame.convert('RGBA')\n            frame = Image.alpha_composite(frame_rgba, emoji_cropped)\n            frame = frame.convert('RGB')\n\n        elif object_type == 'text':\n            from core.typography import draw_text_with_outline\n\n            current_size = int(base_size * scale)\n            current_size = max(10, min(current_size, 500))\n\n            # Create oversized canvas for large text\n            canvas_size = max(frame_width, frame_height, current_size * 10)\n            text_canvas = Image.new('RGB', (canvas_size, canvas_size), bg_color)\n\n            draw_text_with_outline(\n                text_canvas,\n                text=object_data.get('text', 'ZOOM'),\n                position=(canvas_size // 2, canvas_size // 2),\n                font_size=current_size,\n                text_color=object_data.get('text_color', (0, 0, 0)),\n                outline_color=object_data.get('outline_color', (255, 255, 255)),\n                outline_width=max(2, int(current_size * 0.05)),\n                centered=True\n            )\n\n            # Crop to frame\n            left = (canvas_size - frame_width) // 2\n            top = (canvas_size - frame_height) // 2\n            frame = text_canvas.crop((left, top, left + frame_width, top + frame_height))\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_explosion_zoom(\n    emoji: str = '💥',\n    num_frames: int = 20,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create dramatic explosion zoom effect.\n\n    Args:\n        emoji: Emoji to explode\n        num_frames: Number of frames\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Exponential zoom\n        scale = 0.1 * math.exp(t * 5)\n\n        # Add rotation for drama\n        angle = t * 360 * 2\n\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        current_size = int(100 * scale)\n        current_size = max(12, min(current_size, frame_width * 3))\n\n        # Create emoji\n        canvas_size = max(frame_width, frame_height, current_size) * 2\n        emoji_canvas = Image.new('RGBA', (canvas_size, canvas_size), (0, 0, 0, 0))\n\n        draw_emoji_enhanced(\n            emoji_canvas,\n            emoji=emoji,\n            position=(canvas_size // 2 - current_size // 2, canvas_size // 2 - current_size // 2),\n            size=current_size,\n            shadow=False\n        )\n\n        # Rotate\n        emoji_canvas = emoji_canvas.rotate(angle, center=(canvas_size // 2, canvas_size // 2), resample=Image.BICUBIC)\n\n        # Add motion blur for later frames\n        if t > 0.5:\n            blur_amount = int((t - 0.5) * 10)\n            emoji_canvas = emoji_canvas.filter(ImageFilter.GaussianBlur(blur_amount))\n\n        # Crop and composite\n        left = (canvas_size - frame_width) // 2\n        top = (canvas_size - frame_height) // 2\n        emoji_cropped = emoji_canvas.crop((left, top, left + frame_width, top + frame_height))\n\n        frame_rgba = frame.convert('RGBA')\n        frame = Image.alpha_composite(frame_rgba, emoji_cropped)\n        frame = frame.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\ndef create_mind_blown_zoom(\n    emoji: str = '🤯',\n    num_frames: int = 30,\n    frame_width: int = 480,\n    frame_height: int = 480,\n    bg_color: tuple[int, int, int] = (255, 255, 255)\n) -> list[Image.Image]:\n    \"\"\"\n    Create \"mind blown\" dramatic zoom with shake.\n\n    Args:\n        emoji: Emoji to use\n        num_frames: Number of frames\n        frame_width: Frame width\n        frame_height: Frame height\n        bg_color: Background color\n\n    Returns:\n        List of frames\n    \"\"\"\n    frames = []\n\n    for i in range(num_frames):\n        t = i / (num_frames - 1) if num_frames > 1 else 0\n\n        # Zoom in then shake\n        if t < 0.5:\n            scale = interpolate(0.3, 1.2, t * 2, 'ease_out')\n            shake_x = 0\n            shake_y = 0\n        else:\n            scale = 1.2\n            # Shake intensifies\n            shake_intensity = (t - 0.5) * 40\n            shake_x = int(math.sin(t * 50) * shake_intensity)\n            shake_y = int(math.cos(t * 45) * shake_intensity)\n\n        frame = create_blank_frame(frame_width, frame_height, bg_color)\n\n        current_size = int(100 * scale)\n        center_x = frame_width // 2 + shake_x\n        center_y = frame_height // 2 + shake_y\n\n        emoji_canvas = Image.new('RGBA', (frame_width, frame_height), (0, 0, 0, 0))\n        draw_emoji_enhanced(\n            emoji_canvas,\n            emoji=emoji,\n            position=(center_x - current_size // 2, center_y - current_size // 2),\n            size=current_size,\n            shadow=False\n        )\n\n        frame_rgba = frame.convert('RGBA')\n        frame = Image.alpha_composite(frame_rgba, emoji_canvas)\n        frame = frame.convert('RGB')\n\n        frames.append(frame)\n\n    return frames\n\n\n# Example usage\nif __name__ == '__main__':\n    print(\"Creating zoom animations...\")\n\n    builder = GIFBuilder(width=480, height=480, fps=20)\n\n    # Example 1: Zoom in\n    frames = create_zoom_animation(\n        object_type='emoji',\n        object_data={'emoji': '🔍', 'size': 100},\n        num_frames=30,\n        zoom_type='in',\n        scale_range=(0.1, 1.5),\n        easing='ease_out'\n    )\n    builder.add_frames(frames)\n    builder.save('zoom_in.gif', num_colors=128)\n\n    # Example 2: Explosion zoom\n    builder.clear()\n    frames = create_explosion_zoom(emoji='💥', num_frames=20)\n    builder.add_frames(frames)\n    builder.save('zoom_explosion.gif', num_colors=128)\n\n    # Example 3: Mind blown\n    builder.clear()\n    frames = create_mind_blown_zoom(emoji='🤯', num_frames=30)\n    builder.add_frames(frames)\n    builder.save('zoom_mind_blown.gif', num_colors=128)\n\n    print(\"Created zoom animations!\")\n"
  },
  {
    "path": "tailored-resume-generator/SKILL.md",
    "content": "---\nname: tailored-resume-generator\ndescription: Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances\n---\n\n# Tailored Resume Generator\n\n## When to Use This Skill\n\n- Applying for a specific job position\n- Customizing your resume for different industries or roles\n- Highlighting relevant experience for career transitions\n- Optimizing your resume for ATS (Applicant Tracking Systems)\n- Creating multiple resume versions for different job applications\n- Emphasizing specific skills mentioned in job postings\n\n## What This Skill Does\n\n1. **Analyzes Job Descriptions**: Extracts key requirements, skills, qualifications, and keywords from job postings\n2. **Identifies Priorities**: Determines what employers value most based on the job description language and structure\n3. **Tailors Content**: Reorganizes and emphasizes relevant experience, skills, and achievements\n4. **Optimizes Keywords**: Incorporates ATS-friendly keywords naturally throughout the resume\n5. **Formats Professionally**: Creates clean, professional resume layouts suitable for various formats\n6. **Provides Recommendations**: Suggests improvements and highlights gaps to address\n\n## How to Use\n\n### Basic Usage\nProvide a job description and your background information:\n\n```\nI'm applying for this job:\n\n[paste job description]\n\nHere's my background:\n- 5 years as software engineer at TechCorp\n- Led team of 3 developers on mobile app project\n- Expert in Python, JavaScript, React\n- Computer Science degree from State University\n```\n\n### With Existing Resume\nUpload or paste your current resume along with the job description:\n\n```\nPlease tailor my resume for this position:\n\nJob Description:\n[paste job description]\n\nMy Current Resume:\n[paste resume content]\n```\n\n### Career Transition\nWhen changing industries or roles:\n\n```\nI'm transitioning from marketing to product management.\nHere's the job I'm applying for:\n\n[paste job description]\n\nMy transferable experience:\n- 7 years in digital marketing\n- Led cross-functional teams\n- Managed product launches\n- Data analysis and A/B testing\n```\n\n## Example\n\n**User Request:**\n```\nI need a tailored resume for this job:\n\nSenior Data Analyst Position\n\nRequirements:\n- 5+ years experience in data analysis\n- Expert in SQL, Python, and data visualization tools\n- Experience with A/B testing and statistical analysis\n- Strong communication skills to present findings\n- Healthcare industry experience preferred\n\nMy background:\n- Data Analyst at RetailCo (2019-2024)\n- Created dashboards using Tableau and Power BI\n- Built Python scripts for data automation\n- Worked with marketing team on campaign analysis\n- Business Analytics degree\n- Also did 1 year internship at HealthPlus clinic\n```\n\n**Generated Output:**\n\n```markdown\n# JOHN DOE\nEmail: john.doe@email.com | Phone: (555) 123-4567 | LinkedIn: linkedin.com/in/johndoe\n\n## PROFESSIONAL SUMMARY\nResults-driven Data Analyst with 5+ years of experience leveraging SQL, Python, and advanced\nvisualization tools to deliver actionable insights. Proven track record in statistical analysis,\nA/B testing, and cross-functional collaboration. Healthcare industry experience with strong\nability to communicate complex data findings to stakeholders.\n\n## TECHNICAL SKILLS\n- **Data Analysis & Programming**: SQL, Python, Statistical Analysis, A/B Testing\n- **Visualization Tools**: Tableau, Power BI, Advanced Dashboard Development\n- **Data Management**: Data Automation, ETL Processes, Database Optimization\n- **Business Intelligence**: Campaign Analytics, Performance Metrics, KPI Tracking\n\n## PROFESSIONAL EXPERIENCE\n\n**Data Analyst** | RetailCo | 2019 - 2024\n- Designed and implemented 50+ SQL queries and Python automation scripts, reducing manual\n  data processing time by 60%\n- Conducted rigorous A/B testing and statistical analysis for marketing campaigns,\n  improving campaign ROI by 35%\n- Built interactive Tableau and Power BI dashboards for executive team, enabling\n  data-driven decision making\n- Presented analytical findings to cross-functional stakeholders including marketing,\n  operations, and executive leadership\n- Collaborated with marketing team to analyze customer behavior patterns and optimize\n  targeting strategies\n\n**Data Analysis Intern** | HealthPlus Clinic | 2018 - 2019\n- Supported healthcare analytics initiatives by analyzing patient data and operational metrics\n- Gained exposure to healthcare industry data management and HIPAA compliance requirements\n- Assisted in creating reports for clinical staff to improve patient care workflows\n\n## EDUCATION\n\n**Bachelor of Science in Business Analytics**\nState University | Graduated 2018\n\n## KEY ACHIEVEMENTS\n- Reduced data processing time by 60% through Python automation\n- Improved marketing campaign ROI by 35% through A/B testing and optimization\n- Created data visualization system now used across entire organization\n```\n\n**Additional Recommendations:**\n- Consider adding any specific healthcare projects or certifications\n- Quantify more achievements with metrics when possible\n- If you have experience with R or advanced statistical methods, add them\n- Consider mentioning any familiarity with healthcare regulations (HIPAA, etc.)\n\n---\n\n## Instructions\n\nWhen a user requests resume tailoring:\n\n### 1. Gather Information\n\n**Job Description Analysis**:\n- Request the full job description if not provided\n- Ask for the company name and job title\n\n**Candidate Background**:\n- If user provides existing resume, use it as the foundation\n- If not, request:\n  - Work history (job titles, companies, dates, responsibilities)\n  - Education background\n  - Key skills and technical proficiencies\n  - Notable achievements and metrics\n  - Certifications or awards\n  - Any other relevant information\n\n### 2. Analyze Job Requirements\n\nExtract and prioritize:\n- **Must-have qualifications**: Years of experience, required skills, education\n- **Key skills**: Technical tools, methodologies, competencies\n- **Soft skills**: Communication, leadership, teamwork\n- **Industry knowledge**: Domain-specific experience\n- **Keywords**: Repeated terms, phrases, and buzzwords for ATS optimization\n- **Company values**: Cultural fit indicators from job description\n\nCreate a mental map of:\n- Priority 1: Critical requirements (deal-breakers)\n- Priority 2: Important qualifications (strongly desired)\n- Priority 3: Nice-to-have skills (bonus points)\n\n### 3. Map Candidate Experience to Requirements\n\nFor each job requirement:\n- Identify matching experience from candidate's background\n- Find transferable skills if no direct match\n- Note gaps that need to be addressed or de-emphasized\n- Identify unique strengths to highlight\n\n### 4. Structure the Tailored Resume\n\n**Professional Summary** (3-4 lines):\n- Lead with years of experience in the target role/field\n- Include top 3-4 required skills from job description\n- Mention industry experience if relevant\n- Highlight unique value proposition\n\n**Technical/Core Skills Section**:\n- Group skills by category matching job requirements\n- List required tools and technologies first\n- Use exact terminology from job description\n- Only include skills you can substantiate with experience\n\n**Professional Experience**:\n- For each role, emphasize responsibilities and achievements aligned with job requirements\n- Use action verbs: Led, Developed, Implemented, Optimized, Managed, Created, Analyzed\n- **Quantify achievements**: Include numbers, percentages, timeframes, scale\n- Reorder bullet points to prioritize most relevant experience\n- Use keywords naturally from job description\n- Format: **[Action Verb] + [What] + [How/Why] + [Result/Impact]**\n\n**Education**:\n- List degrees, certifications relevant to position\n- Include relevant coursework if early career\n- Add certifications that match job requirements\n\n**Optional Sections** (if applicable):\n- Certifications & Licenses\n- Publications or Speaking Engagements\n- Awards & Recognition\n- Volunteer Work (if relevant to role)\n- Projects (especially for technical roles)\n\n### 5. Optimize for ATS (Applicant Tracking Systems)\n\n- Use standard section headings (Professional Experience, Education, Skills)\n- Incorporate exact keywords from job description naturally\n- Avoid tables, graphics, headers/footers, or complex formatting\n- Use standard fonts and bullet points\n- Include both acronyms and full terms (e.g., \"SQL (Structured Query Language)\")\n- Match job title terminology where truthful\n\n### 6. Format and Present\n\n**Format Options**:\n- **Markdown**: Clean, readable, easy to copy\n- **Plain Text**: ATS-optimized, safe for all systems\n- **Tips for Word/PDF**: Provide formatting guidance\n\n**Resume Structure Guidelines**:\n- Keep to 1 page for <10 years experience, 2 pages for 10+ years\n- Use consistent formatting and spacing\n- Ensure contact information is prominent\n- Use reverse chronological order (most recent first)\n- Maintain clean, scannable layout with white space\n\n### 7. Provide Strategic Recommendations\n\nAfter presenting the tailored resume, offer:\n\n**Strengths Analysis**:\n- What makes this candidate competitive\n- Unique qualifications to emphasize in cover letter or interview\n\n**Gap Analysis**:\n- Requirements not fully met\n- Suggestions for addressing gaps (courses, projects, reframing experience)\n\n**Interview Preparation Tips**:\n- Key talking points aligned with resume\n- Stories to prepare based on job requirements\n- Questions to ask that demonstrate fit\n\n**Cover Letter Hooks**:\n- Suggest 2-3 opening lines for cover letter\n- Key achievements to expand upon\n\n### 8. Iterate and Refine\n\nAsk if user wants to:\n- Adjust emphasis or tone\n- Add or remove sections\n- Generate alternative versions for different roles\n- Create format variations (traditional vs. modern)\n- Develop role-specific versions (if applying to multiple similar positions)\n\n### 9. Best Practices to Follow\n\n**Do**:\n- Be truthful and accurate - never fabricate experience\n- Use industry-standard terminology\n- Quantify achievements with specific metrics\n- Tailor each resume to specific job\n- Proofread for grammar and consistency\n- Keep language concise and impactful\n\n**Don't**:\n- Include personal information (age, marital status, photo unless requested)\n- Use first-person pronouns (I, me, my)\n- Include references (\"available upon request\" is outdated)\n- List every job if career is 20+ years (focus on relevant, recent experience)\n- Use generic templates without customization\n- Exceed 2 pages unless very senior role\n\n### 10. Special Considerations\n\n**Career Changers**:\n- Use functional or hybrid resume format\n- Emphasize transferable skills\n- Create compelling narrative in summary\n- Focus on relevant projects and coursework\n\n**Recent Graduates**:\n- Lead with education\n- Include relevant coursework, projects, internships\n- Emphasize leadership in student organizations\n- Include GPA if 3.5+\n\n**Senior Executives**:\n- Lead with executive summary\n- Focus on leadership and strategic impact\n- Include board memberships, speaking engagements\n- Emphasize revenue growth, team building, vision\n\n**Technical Roles**:\n- Include technical skills section prominently\n- List programming languages, frameworks, tools\n- Include GitHub, portfolio, or project links\n- Mention methodologies (Agile, Scrum, etc.)\n\n**Creative Roles**:\n- Include link to portfolio\n- Highlight creative achievements and campaigns\n- Mention tools and software proficiencies\n- Consider more creative formatting (while maintaining ATS compatibility)\n\n---\n\n## Tips for Best Results\n\n- **Be specific**: Provide complete job descriptions and detailed background information\n- **Share metrics**: Include numbers, percentages, and quantifiable achievements when describing your experience\n- **Indicate format preference**: Let the skill know if you need ATS-optimized, creative, or traditional format\n- **Mention constraints**: Share any specific requirements (page limits, sections to include/exclude)\n- **Iterate**: Don't hesitate to ask for revisions or alternative approaches\n- **Multiple applications**: Generate separate tailored versions for different roles\n\n## Privacy Note\n\nThis skill processes your personal and professional information to generate tailored resumes. Always review the output before submitting to ensure accuracy and appropriateness. Remove or modify any information you prefer not to share with potential employers.\n"
  },
  {
    "path": "template-skill/SKILL.md",
    "content": "---\nname: template-skill\ndescription: Replace with description of the skill and when Claude should use it.\n---\n\n# Insert instructions below\n"
  },
  {
    "path": "theme-factory/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "theme-factory/SKILL.md",
    "content": "---\nname: theme-factory\ndescription: Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.\nlicense: Complete terms in LICENSE.txt\n---\n\n\n# Theme Factory Skill\n\nThis skill provides a curated collection of professional font and color themes themes, each with carefully selected color palettes and font pairings. Once a theme is chosen, it can be applied to any artifact.\n\n## Purpose\n\nTo apply consistent, professional styling to presentation slide decks, use this skill. Each theme includes:\n- A cohesive color palette with hex codes\n- Complementary font pairings for headers and body text\n- A distinct visual identity suitable for different contexts and audiences\n\n## Usage Instructions\n\nTo apply styling to a slide deck or other artifact:\n\n1. **Show the theme showcase**: Display the `theme-showcase.pdf` file to allow users to see all available themes visually. Do not make any modifications to it; simply show the file for viewing.\n2. **Ask for their choice**: Ask which theme to apply to the deck\n3. **Wait for selection**: Get explicit confirmation about the chosen theme\n4. **Apply the theme**: Once a theme has been chosen, apply the selected theme's colors and fonts to the deck/artifact\n\n## Themes Available\n\nThe following 10 themes are available, each showcased in `theme-showcase.pdf`:\n\n1. **Ocean Depths** - Professional and calming maritime theme\n2. **Sunset Boulevard** - Warm and vibrant sunset colors\n3. **Forest Canopy** - Natural and grounded earth tones\n4. **Modern Minimalist** - Clean and contemporary grayscale\n5. **Golden Hour** - Rich and warm autumnal palette\n6. **Arctic Frost** - Cool and crisp winter-inspired theme\n7. **Desert Rose** - Soft and sophisticated dusty tones\n8. **Tech Innovation** - Bold and modern tech aesthetic\n9. **Botanical Garden** - Fresh and organic garden colors\n10. **Midnight Galaxy** - Dramatic and cosmic deep tones\n\n## Theme Details\n\nEach theme is defined in the `themes/` directory with complete specifications including:\n- Cohesive color palette with hex codes\n- Complementary font pairings for headers and body text\n- Distinct visual identity suitable for different contexts and audiences\n\n## Application Process\n\nAfter a preferred theme is selected:\n1. Read the corresponding theme file from the `themes/` directory\n2. Apply the specified colors and fonts consistently throughout the deck\n3. Ensure proper contrast and readability\n4. Maintain the theme's visual identity across all slides\n\n## Create your Own Theme\nTo handle cases where none of the existing themes work for an artifact, create a custom theme. Based on provided inputs, generate a new theme similar to the ones above. Give the theme a similar name describing what the font/color combinations represent. Use any basic description provided to choose appropriate colors/fonts. After generating the theme, show it for review and verification. Following that, apply the theme as described above.\n"
  },
  {
    "path": "theme-factory/themes/arctic-frost.md",
    "content": "# Arctic Frost\n\nA cool and crisp winter-inspired theme that conveys clarity, precision, and professionalism.\n\n## Color Palette\n\n- **Ice Blue**: `#d4e4f7` - Light backgrounds and highlights\n- **Steel Blue**: `#4a6fa5` - Primary accent color\n- **Silver**: `#c0c0c0` - Metallic accent elements\n- **Crisp White**: `#fafafa` - Clean backgrounds and text\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nHealthcare presentations, technology solutions, winter sports, clean tech, pharmaceutical content.\n"
  },
  {
    "path": "theme-factory/themes/botanical-garden.md",
    "content": "# Botanical Garden\n\nA fresh and organic theme featuring vibrant garden-inspired colors for lively presentations.\n\n## Color Palette\n\n- **Fern Green**: `#4a7c59` - Rich natural green\n- **Marigold**: `#f9a620` - Bright floral accent\n- **Terracotta**: `#b7472a` - Earthy warm tone\n- **Cream**: `#f5f3ed` - Soft neutral backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Serif Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nGarden centers, food presentations, farm-to-table content, botanical brands, natural products.\n"
  },
  {
    "path": "theme-factory/themes/desert-rose.md",
    "content": "# Desert Rose\n\nA soft and sophisticated theme with dusty, muted tones perfect for elegant presentations.\n\n## Color Palette\n\n- **Dusty Rose**: `#d4a5a5` - Soft primary color\n- **Clay**: `#b87d6d` - Earthy accent\n- **Sand**: `#e8d5c4` - Warm neutral backgrounds\n- **Deep Burgundy**: `#5d2e46` - Rich dark contrast\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nFashion presentations, beauty brands, wedding planning, interior design, boutique businesses.\n"
  },
  {
    "path": "theme-factory/themes/forest-canopy.md",
    "content": "# Forest Canopy\n\nA natural and grounded theme featuring earth tones inspired by dense forest environments.\n\n## Color Palette\n\n- **Forest Green**: `#2d4a2b` - Primary dark green\n- **Sage**: `#7d8471` - Muted green accent\n- **Olive**: `#a4ac86` - Light accent color\n- **Ivory**: `#faf9f6` - Backgrounds and text\n\n## Typography\n\n- **Headers**: FreeSerif Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nEnvironmental presentations, sustainability reports, outdoor brands, wellness content, organic products.\n"
  },
  {
    "path": "theme-factory/themes/golden-hour.md",
    "content": "# Golden Hour\n\nA rich and warm autumnal palette that creates an inviting and sophisticated atmosphere.\n\n## Color Palette\n\n- **Mustard Yellow**: `#f4a900` - Bold primary accent\n- **Terracotta**: `#c1666b` - Warm secondary color\n- **Warm Beige**: `#d4b896` - Neutral backgrounds\n- **Chocolate Brown**: `#4a403a` - Dark text and anchors\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nRestaurant presentations, hospitality brands, fall campaigns, cozy lifestyle content, artisan products.\n"
  },
  {
    "path": "theme-factory/themes/midnight-galaxy.md",
    "content": "# Midnight Galaxy\n\nA dramatic and cosmic theme with deep purples and mystical tones for impactful presentations.\n\n## Color Palette\n\n- **Deep Purple**: `#2b1e3e` - Rich dark base\n- **Cosmic Blue**: `#4a4e8f` - Mystical mid-tone\n- **Lavender**: `#a490c2` - Soft accent color\n- **Silver**: `#e6e6fa` - Light highlights and text\n\n## Typography\n\n- **Headers**: FreeSans Bold\n- **Body Text**: FreeSans\n\n## Best Used For\n\nEntertainment industry, gaming presentations, nightlife venues, luxury brands, creative agencies.\n"
  },
  {
    "path": "theme-factory/themes/modern-minimalist.md",
    "content": "# Modern Minimalist\n\nA clean and contemporary theme with a sophisticated grayscale palette for maximum versatility.\n\n## Color Palette\n\n- **Charcoal**: `#36454f` - Primary dark color\n- **Slate Gray**: `#708090` - Medium gray for accents\n- **Light Gray**: `#d3d3d3` - Backgrounds and dividers\n- **White**: `#ffffff` - Text and clean backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nTech presentations, architecture portfolios, design showcases, modern business proposals, data visualization.\n"
  },
  {
    "path": "theme-factory/themes/ocean-depths.md",
    "content": "# Ocean Depths\n\nA professional and calming maritime theme that evokes the serenity of deep ocean waters.\n\n## Color Palette\n\n- **Deep Navy**: `#1a2332` - Primary background color\n- **Teal**: `#2d8b8b` - Accent color for highlights and emphasis\n- **Seafoam**: `#a8dadc` - Secondary accent for lighter elements\n- **Cream**: `#f1faee` - Text and light backgrounds\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nCorporate presentations, financial reports, professional consulting decks, trust-building content.\n"
  },
  {
    "path": "theme-factory/themes/sunset-boulevard.md",
    "content": "# Sunset Boulevard\n\nA warm and vibrant theme inspired by golden hour sunsets, perfect for energetic and creative presentations.\n\n## Color Palette\n\n- **Burnt Orange**: `#e76f51` - Primary accent color\n- **Coral**: `#f4a261` - Secondary warm accent\n- **Warm Sand**: `#e9c46a` - Highlighting and backgrounds\n- **Deep Purple**: `#264653` - Dark contrast and text\n\n## Typography\n\n- **Headers**: DejaVu Serif Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nCreative pitches, marketing presentations, lifestyle brands, event promotions, inspirational content.\n"
  },
  {
    "path": "theme-factory/themes/tech-innovation.md",
    "content": "# Tech Innovation\n\nA bold and modern theme with high-contrast colors perfect for cutting-edge technology presentations.\n\n## Color Palette\n\n- **Electric Blue**: `#0066ff` - Vibrant primary accent\n- **Neon Cyan**: `#00ffff` - Bright highlight color\n- **Dark Gray**: `#1e1e1e` - Deep backgrounds\n- **White**: `#ffffff` - Clean text and contrast\n\n## Typography\n\n- **Headers**: DejaVu Sans Bold\n- **Body Text**: DejaVu Sans\n\n## Best Used For\n\nTech startups, software launches, innovation showcases, AI/ML presentations, digital transformation content.\n"
  },
  {
    "path": "twitter-algorithm-optimizer/SKILL.md",
    "content": "---\nname: twitter-algorithm-optimizer\ndescription: Analyze and optimize tweets for maximum reach using Twitter's open-source algorithm insights. Rewrite and edit user tweets to improve engagement and visibility based on how the recommendation system ranks content.\nlicense: AGPL-3.0 (referencing Twitter's algorithm source)\n---\n\n# Twitter Algorithm Optimizer\n\n## When to Use This Skill\n\nUse this skill when you need to:\n- **Optimize tweet drafts** for maximum reach and engagement\n- **Understand why** a tweet might not perform well algorithmically\n- **Rewrite tweets** to align with Twitter's ranking mechanisms\n- **Improve content strategy** based on the actual ranking algorithms\n- **Debug underperforming content** and increase visibility\n- **Maximize engagement signals** that Twitter's algorithms track\n\n## What This Skill Does\n\n1. **Analyzes tweets** against Twitter's core recommendation algorithms\n2. **Identifies optimization opportunities** based on engagement signals\n3. **Rewrites and edits tweets** to improve algorithmic ranking\n4. **Explains the \"why\"** behind recommendations using algorithm insights\n5. **Applies Real-graph, SimClusters, and TwHIN principles** to content strategy\n6. **Provides engagement-boosting tactics** grounded in Twitter's actual systems\n\n## How It Works: Twitter's Algorithm Architecture\n\nTwitter's recommendation system uses multiple interconnected models:\n\n### Core Ranking Models\n\n**Real-graph**: Predicts interaction likelihood between users\n- Determines if your followers will engage with your content\n- Affects how widely Twitter shows your tweet to others\n- Key signal: Will followers like, reply, or retweet this?\n\n**SimClusters**: Community detection with sparse embeddings\n- Identifies communities of users with similar interests\n- Determines if your tweet resonates within specific communities\n- Key strategy: Make content that appeals to tight communities who will engage\n\n**TwHIN**: Knowledge graph embeddings for users and posts\n- Maps relationships between users and content topics\n- Helps Twitter understand if your tweet fits your follower interests\n- Key strategy: Stay in your niche or clearly signal topic shifts\n\n**Tweepcred**: User reputation/authority scoring\n- Higher-credibility users get more distribution\n- Your past engagement history affects current tweet reach\n- Key strategy: Build reputation through consistent engagement\n\n### Engagement Signals Tracked\n\nTwitter's **Unified User Actions** service tracks both explicit and implicit signals:\n\n**Explicit Signals** (high weight):\n- Likes (direct positive signal)\n- Replies (indicates valuable content worth discussing)\n- Retweets (strongest signal - users want to share it)\n- Quote tweets (engaged discussion)\n\n**Implicit Signals** (also weighted):\n- Profile visits (curiosity about the author)\n- Clicks/link clicks (content deemed useful enough to explore)\n- Time spent (users reading/considering your tweet)\n- Saves/bookmarks (plan to return later)\n\n**Negative Signals**:\n- Block/report (Twitter penalizes this heavily)\n- Mute/unfollow (person doesn't want your content)\n- Skip/scroll past quickly (low engagement)\n\n### The Feed Generation Process\n\nYour tweet reaches users through this pipeline:\n\n1. **Candidate Retrieval** - Multiple sources find candidate tweets:\n   - Search Index (relevant keyword matches)\n   - UTEG (timeline engagement graph - following relationships)\n   - Tweet-mixer (trending/viral content)\n\n2. **Ranking** - ML models rank candidates by predicted engagement:\n   - Will THIS user engage with THIS tweet?\n   - How quickly will engagement happen?\n   - Will it spread to non-followers?\n\n3. **Filtering** - Remove blocked content, apply preferences\n\n4. **Delivery** - Show ranked feed to user\n\n## Optimization Strategies Based on Algorithm Insights\n\n### 1. Maximize Real-graph (Follower Engagement)\n\n**Strategy**: Make content your followers WILL engage with\n\n- **Know your audience**: Reference topics they care about\n- **Ask questions**: Direct questions get more replies than statements\n- **Create controversy (safely)**: Debate attracts engagement (but avoid blocks/reports)\n- **Tag related creators**: Increases visibility through networks\n- **Post when followers are active**: Better early engagement means better ranking\n\n**Example Optimization**:\n- ❌ \"I think climate policy is important\"\n- ✅ \"Hot take: Current climate policy ignores nuclear energy. Thoughts?\" (triggers replies)\n\n### 2. Leverage SimClusters (Community Resonance)\n\n**Strategy**: Find and serve tight communities deeply interested in your topic\n\n- **Pick ONE clear topic**: Don't confuse the algorithm with mixed messages\n- **Use community language**: Reference shared memes, inside jokes, terminology\n- **Provide value to the niche**: Be genuinely useful to that specific community\n- **Encourage community-to-community sharing**: Quotes that spark discussion\n- **Build in your lane**: Consistency helps algorithm understand your topic\n\n**Example Optimization**:\n- ❌ \"I use many programming languages\"\n- ✅ \"Rust's ownership system is the most underrated feature. Here's why...\" (targets specific dev community)\n\n### 3. Improve TwHIN Mapping (Content-User Fit)\n\n**Strategy**: Make your content clearly relevant to your established identity\n\n- **Signal your expertise**: Lead with domain knowledge\n- **Consistency matters**: Stay in your lanes (or clearly announce a new direction)\n- **Use specific terminology**: Helps algorithm categorize you correctly\n- **Reference your past wins**: \"Following up on my tweet about X...\"\n- **Build topical authority**: Multiple tweets on same topic strengthen the connection\n\n**Example Optimization**:\n- ❌ \"I like lots of things\" (vague, confuses algorithm)\n- ✅ \"My 3rd consecutive framework review as a full-stack engineer\" (establishes authority)\n\n### 4. Boost Tweepcred (Authority/Credibility)\n\n**Strategy**: Build reputation through engagement consistency\n\n- **Reply to top creators**: Interaction with high-credibility accounts boosts visibility\n- **Quote interesting tweets**: Adds value and signals engagement\n- **Avoid engagement bait**: Doesn't build real credibility\n- **Be consistent**: Regular quality posting beats sporadic viral attempts\n- **Engage deeply**: Quality replies and discussions matter more than volume\n\n**Example Optimization**:\n- ❌ \"RETWEET IF...\" (engagement bait, damages credibility over time)\n- ✅ \"Thoughtful critique of the approach in [linked tweet]\" (builds authority)\n\n### 5. Maximize Engagement Signals\n\n**Explicit Signal Triggers**:\n\n**For Likes**:\n- Novel insights or memorable phrasing\n- Validation of audience beliefs\n- Useful/actionable information\n- Strong opinions with supporting evidence\n\n**For Replies**:\n- Ask a direct question\n- Create a debate\n- Request opinions\n- Share incomplete thoughts (invites completion)\n\n**For Retweets**:\n- Useful information people want to share\n- Representational value (tweet speaks for them)\n- Entertainment that entertains their followers\n- Information advantage (breaking news first)\n\n**For Bookmarks/Saves**:\n- Tutorials or how-tos\n- Data/statistics they'll reference later\n- Inspiration or motivation\n- Jokes/entertainment they'll want to see again\n\n**Example Optimization**:\n- ❌ \"Check out this tool\" (passive)\n- ✅ \"This tool saved me 5 hours this week. Here's how to set it up...\" (actionable, retweet-worthy)\n\n### 6. Prevent Negative Signals\n\n**Avoid**:\n- Inflammatory content likely to be reported\n- Targeted harassment (gets algorithmic penalty)\n- Misleading/false claims (damages credibility)\n- Off-brand pivots (confuses the algorithm)\n- Reply-guy syndrome (too many low-value replies)\n\n## How to Optimize Your Tweets\n\n### Step 1: Identify the Core Message\n- What's the single most important thing this tweet communicates?\n- Who should care about this?\n- What action/engagement do you want?\n\n### Step 2: Map to Algorithm Strategy\n- Which Real-graph follower segment will engage? (Followers who care about X)\n- Which SimCluster community? (Niche interested in Y)\n- How does this fit your TwHIN identity? (Your established expertise)\n- Does this boost or hurt Tweepcred?\n\n### Step 3: Optimize for Signals\n- Does it trigger replies? (Ask a question, create debate)\n- Is it retweet-worthy? (Usefulness, entertainment, representational value)\n- Will followers like it? (Novel, validating, actionable)\n- Could it go viral? (Community resonance + network effects)\n\n### Step 4: Check Against Negatives\n- Any blocks/reports risk?\n- Any confusion about your identity?\n- Any engagement bait that damages credibility?\n- Any inflammatory language that hurts Tweepcred?\n\n## Example Optimizations\n\n### Example 1: Developer Tweet\n\n**Original**:\n> \"I fixed a bug today\"\n\n**Algorithm Analysis**:\n- No clear audience - too generic\n- No engagement signals - statements don't trigger replies\n- No Real-graph trigger - followers won't engage strongly\n- No SimCluster resonance - could apply to any developer\n\n**Optimized**:\n> \"Spent 2 hours debugging, turned out I was missing one semicolon. The best part? The linter didn't catch it.\n>\n> What's your most embarrassing bug? Drop it in replies 👇\"\n\n**Why It Works**:\n- SimCluster trigger: Specific developer community\n- Real-graph trigger: Direct question invites replies\n- Tweepcred: Relatable vulnerability builds connection\n- Engagement: Likely replies (others share embarrassing bugs)\n\n### Example 2: Product Launch Tweet\n\n**Original**:\n> \"We launched a new feature today. Check it out.\"\n\n**Algorithm Analysis**:\n- Passive voice - doesn't indicate impact\n- No specific benefit - followers don't know why to care\n- No community resonance - generic\n- Engagement bait risk if it feels like self-promotion\n\n**Optimized**:\n> \"Spent 6 months on the one feature our users asked for most: export to PDF.\n>\n> 10x improvement in report generation time. Already live.\n>\n> What export format do you want next?\"\n\n**Why It Works**:\n- Real-graph: Followers in your product space will engage\n- Specificity: \"PDF export\" + \"10x improvement\" triggers bookmarks (useful info)\n- Question: Ends with engagement trigger\n- Authority: You spent 6 months (shows credibility)\n- SimCluster: Product management/SaaS community resonates\n\n### Example 3: Opinion Tweet\n\n**Original**:\n> \"I think remote work is better than office work\"\n\n**Algorithm Analysis**:\n- Vague opinion - doesn't invite engagement\n- Could be debated either way - no clear position\n- No Real-graph hooks - followers unclear if they should care\n- Generic topic - dilutes your personal brand\n\n**Optimized**:\n> \"Hot take: remote work works great for async tasks but kills creative collaboration.\n>\n> We're now hybrid: deep focus days remote, collab days in office.\n>\n> What's your team's balance? Genuinely curious what works.\"\n\n**Why It Works**:\n- Clear position: Not absolutes, nuanced stance\n- Debate trigger: \"Hot take\" signals discussion opportunity\n- Question: Direct engagement request\n- Real-graph: Followers in your industry will have opinions\n- SimCluster: CTOs, team leads, engineering managers will relate\n- Tweepcred: Nuanced thinking builds authority\n\n## Best Practices for Algorithm Optimization\n\n1. **Quality Over Virality**: Consistent engagement from your community beats occasional viral moments\n2. **Community First**: Deep resonance with 100 engaged followers beats shallow reach to 10,000\n3. **Authenticity Matters**: The algorithm rewards genuine engagement, not manipulation\n4. **Timing Helps**: Engage early when tweet is fresh (first hour critical)\n5. **Build Threads**: Threaded tweets often get more engagement than single tweets\n6. **Follow Up**: Reply to replies quickly - Twitter's algorithm favors active conversation\n7. **Avoid Spam**: Engagement pods and bots hurt long-term credibility\n8. **Track Your Performance**: Notice what YOUR audience engages with and iterate\n\n## Common Pitfalls to Avoid\n\n- **Generic statements**: Doesn't trigger algorithm (too vague)\n- **Pure engagement bait**: \"Like if you agree\" - hurts credibility long-term\n- **Unclear audience**: Who should care? If unclear, algorithm won't push it far\n- **Off-brand pivots**: Confuses algorithm about your identity\n- **Over-frequency**: Spamming hurts engagement rate metrics\n- **Toxicity**: Blocks/reports heavily penalize future reach\n- **No calls to action**: Passive tweets underperform\n\n## When to Ask for Algorithm Optimization\n\nUse this skill when:\n- You've drafted a tweet and want to maximize reach\n- A tweet underperformed and you want to understand why\n- You're launching important content and want algorithm advantage\n- You're building audience in a specific niche\n- You want to become known for something specific\n- You're debugging inconsistent engagement rates\n\nUse Claude without this skill for:\n- General writing and grammar fixes\n- Tone adjustments not related to algorithm\n- Off-Twitter content (LinkedIn, Medium, blogs, etc.)\n- Personal conversations and casual tweets"
  },
  {
    "path": "video-downloader/SKILL.md",
    "content": "---\nname: youtube-downloader\ndescription: Download YouTube videos with customizable quality and format options. Use this skill when the user asks to download, save, or grab YouTube videos. Supports various quality settings (best, 1080p, 720p, 480p, 360p), multiple formats (mp4, webm, mkv), and audio-only downloads as MP3.\n---\n\n# YouTube Video Downloader\n\nDownload YouTube videos with full control over quality and format settings.\n\n## Quick Start\n\nThe simplest way to download a video:\n\n```bash\npython scripts/download_video.py \"https://www.youtube.com/watch?v=VIDEO_ID\"\n```\n\nThis downloads the video in best available quality as MP4 to `/mnt/user-data/outputs/`.\n\n## Options\n\n### Quality Settings\n\nUse `-q` or `--quality` to specify video quality:\n\n- `best` (default): Highest quality available\n- `1080p`: Full HD\n- `720p`: HD\n- `480p`: Standard definition\n- `360p`: Lower quality\n- `worst`: Lowest quality available\n\nExample:\n```bash\npython scripts/download_video.py \"URL\" -q 720p\n```\n\n### Format Options\n\nUse `-f` or `--format` to specify output format (video downloads only):\n\n- `mp4` (default): Most compatible\n- `webm`: Modern format\n- `mkv`: Matroska container\n\nExample:\n```bash\npython scripts/download_video.py \"URL\" -f webm\n```\n\n### Audio Only\n\nUse `-a` or `--audio-only` to download only audio as MP3:\n\n```bash\npython scripts/download_video.py \"URL\" -a\n```\n\n### Custom Output Directory\n\nUse `-o` or `--output` to specify a different output directory:\n\n```bash\npython scripts/download_video.py \"URL\" -o /path/to/directory\n```\n\n## Complete Examples\n\n1. Download video in 1080p as MP4:\n```bash\npython scripts/download_video.py \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\" -q 1080p\n```\n\n2. Download audio only as MP3:\n```bash\npython scripts/download_video.py \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\" -a\n```\n\n3. Download in 720p as WebM to custom directory:\n```bash\npython scripts/download_video.py \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\" -q 720p -f webm -o /custom/path\n```\n\n## How It Works\n\nThe skill uses `yt-dlp`, a robust YouTube downloader that:\n- Automatically installs itself if not present\n- Fetches video information before downloading\n- Selects the best available streams matching your criteria\n- Merges video and audio streams when needed\n- Supports a wide range of YouTube video formats\n\n## Important Notes\n\n- Downloads are saved to `/mnt/user-data/outputs/` by default\n- Video filename is automatically generated from the video title\n- The script handles installation of yt-dlp automatically\n- Only single videos are downloaded (playlists are skipped by default)\n- Higher quality videos may take longer to download and use more disk space"
  },
  {
    "path": "video-downloader/scripts/download_video.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nYouTube Video Downloader\nDownloads videos from YouTube with customizable quality and format options.\n\"\"\"\n\nimport argparse\nimport sys\nimport subprocess\nimport json\n\n\ndef check_yt_dlp():\n    \"\"\"Check if yt-dlp is installed, install if not.\"\"\"\n    try:\n        subprocess.run([\"yt-dlp\", \"--version\"], capture_output=True, check=True)\n    except (subprocess.CalledProcessError, FileNotFoundError):\n        print(\"yt-dlp not found. Installing...\")\n        subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"--break-system-packages\", \"yt-dlp\"], check=True)\n\n\ndef get_video_info(url):\n    \"\"\"Get information about the video without downloading.\"\"\"\n    result = subprocess.run(\n        [\"yt-dlp\", \"--dump-json\", \"--no-playlist\", url],\n        capture_output=True,\n        text=True,\n        check=True\n    )\n    return json.loads(result.stdout)\n\n\ndef download_video(url, output_path=\"/mnt/user-data/outputs\", quality=\"best\", format_type=\"mp4\", audio_only=False):\n    \"\"\"\n    Download a YouTube video.\n    \n    Args:\n        url: YouTube video URL\n        output_path: Directory to save the video\n        quality: Quality setting (best, 1080p, 720p, 480p, 360p, worst)\n        format_type: Output format (mp4, webm, mkv, etc.)\n        audio_only: Download only audio (mp3)\n    \"\"\"\n    check_yt_dlp()\n    \n    # Build command\n    cmd = [\"yt-dlp\"]\n    \n    if audio_only:\n        cmd.extend([\n            \"-x\",  # Extract audio\n            \"--audio-format\", \"mp3\",\n            \"--audio-quality\", \"0\",  # Best quality\n        ])\n    else:\n        # Video quality settings\n        if quality == \"best\":\n            format_string = \"bestvideo+bestaudio/best\"\n        elif quality == \"worst\":\n            format_string = \"worstvideo+worstaudio/worst\"\n        else:\n            # Specific resolution (e.g., 1080p, 720p)\n            height = quality.replace(\"p\", \"\")\n            format_string = f\"bestvideo[height<={height}]+bestaudio/best[height<={height}]\"\n        \n        cmd.extend([\n            \"-f\", format_string,\n            \"--merge-output-format\", format_type,\n        ])\n    \n    # Output template\n    cmd.extend([\n        \"-o\", f\"{output_path}/%(title)s.%(ext)s\",\n        \"--no-playlist\",  # Don't download playlists by default\n    ])\n    \n    cmd.append(url)\n    \n    print(f\"Downloading from: {url}\")\n    print(f\"Quality: {quality}\")\n    print(f\"Format: {'mp3 (audio only)' if audio_only else format_type}\")\n    print(f\"Output: {output_path}\\n\")\n    \n    try:\n        # Get video info first\n        info = get_video_info(url)\n        print(f\"Title: {info.get('title', 'Unknown')}\")\n        print(f\"Duration: {info.get('duration', 0) // 60}:{info.get('duration', 0) % 60:02d}\")\n        print(f\"Uploader: {info.get('uploader', 'Unknown')}\\n\")\n        \n        # Download the video\n        subprocess.run(cmd, check=True)\n        print(f\"\\n✅ Download complete!\")\n        return True\n    except subprocess.CalledProcessError as e:\n        print(f\"\\n❌ Error downloading video: {e}\")\n        return False\n    except Exception as e:\n        print(f\"\\n❌ Error: {e}\")\n        return False\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description=\"Download YouTube videos with customizable quality and format\"\n    )\n    parser.add_argument(\"url\", help=\"YouTube video URL\")\n    parser.add_argument(\n        \"-o\", \"--output\",\n        default=\"/mnt/user-data/outputs\",\n        help=\"Output directory (default: /mnt/user-data/outputs)\"\n    )\n    parser.add_argument(\n        \"-q\", \"--quality\",\n        default=\"best\",\n        choices=[\"best\", \"1080p\", \"720p\", \"480p\", \"360p\", \"worst\"],\n        help=\"Video quality (default: best)\"\n    )\n    parser.add_argument(\n        \"-f\", \"--format\",\n        default=\"mp4\",\n        choices=[\"mp4\", \"webm\", \"mkv\"],\n        help=\"Video format (default: mp4)\"\n    )\n    parser.add_argument(\n        \"-a\", \"--audio-only\",\n        action=\"store_true\",\n        help=\"Download only audio as MP3\"\n    )\n    \n    args = parser.parse_args()\n    \n    success = download_video(\n        url=args.url,\n        output_path=args.output,\n        quality=args.quality,\n        format_type=args.format,\n        audio_only=args.audio_only\n    )\n    \n    sys.exit(0 if success else 1)\n\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "webapp-testing/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "webapp-testing/SKILL.md",
    "content": "---\nname: webapp-testing\ndescription: Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.\nlicense: Complete terms in LICENSE.txt\n---\n\n# Web Application Testing\n\nTo test local web applications, write native Python Playwright scripts.\n\n**Helper Scripts Available**:\n- `scripts/with_server.py` - Manages server lifecycle (supports multiple servers)\n\n**Always run scripts with `--help` first** to see usage. DO NOT read the source until you try running the script first and find that a customized solution is abslutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window.\n\n## Decision Tree: Choosing Your Approach\n\n```\nUser task → Is it static HTML?\n    ├─ Yes → Read HTML file directly to identify selectors\n    │         ├─ Success → Write Playwright script using selectors\n    │         └─ Fails/Incomplete → Treat as dynamic (below)\n    │\n    └─ No (dynamic webapp) → Is the server already running?\n        ├─ No → Run: python scripts/with_server.py --help\n        │        Then use the helper + write simplified Playwright script\n        │\n        └─ Yes → Reconnaissance-then-action:\n            1. Navigate and wait for networkidle\n            2. Take screenshot or inspect DOM\n            3. Identify selectors from rendered state\n            4. Execute actions with discovered selectors\n```\n\n## Example: Using with_server.py\n\nTo start a server, run `--help` first, then use the helper:\n\n**Single server:**\n```bash\npython scripts/with_server.py --server \"npm run dev\" --port 5173 -- python your_automation.py\n```\n\n**Multiple servers (e.g., backend + frontend):**\n```bash\npython scripts/with_server.py \\\n  --server \"cd backend && python server.py\" --port 3000 \\\n  --server \"cd frontend && npm run dev\" --port 5173 \\\n  -- python your_automation.py\n```\n\nTo create an automation script, include only Playwright logic (servers are managed automatically):\n```python\nfrom playwright.sync_api import sync_playwright\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode\n    page = browser.new_page()\n    page.goto('http://localhost:5173') # Server already running and ready\n    page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute\n    # ... your automation logic\n    browser.close()\n```\n\n## Reconnaissance-Then-Action Pattern\n\n1. **Inspect rendered DOM**:\n   ```python\n   page.screenshot(path='/tmp/inspect.png', full_page=True)\n   content = page.content()\n   page.locator('button').all()\n   ```\n\n2. **Identify selectors** from inspection results\n\n3. **Execute actions** using discovered selectors\n\n## Common Pitfall\n\n❌ **Don't** inspect the DOM before waiting for `networkidle` on dynamic apps\n✅ **Do** wait for `page.wait_for_load_state('networkidle')` before inspection\n\n## Best Practices\n\n- **Use bundled scripts as black boxes** - To accomplish a task, consider whether one of the scripts available in `scripts/` can help. These scripts handle common, complex workflows reliably without cluttering the context window. Use `--help` to see usage, then invoke directly. \n- Use `sync_playwright()` for synchronous scripts\n- Always close the browser when done\n- Use descriptive selectors: `text=`, `role=`, CSS selectors, or IDs\n- Add appropriate waits: `page.wait_for_selector()` or `page.wait_for_timeout()`\n\n## Reference Files\n\n- **examples/** - Examples showing common patterns:\n  - `element_discovery.py` - Discovering buttons, links, and inputs on a page\n  - `static_html_automation.py` - Using file:// URLs for local HTML\n  - `console_logging.py` - Capturing console logs during automation"
  },
  {
    "path": "webapp-testing/examples/console_logging.py",
    "content": "from playwright.sync_api import sync_playwright\n\n# Example: Capturing console logs during browser automation\n\nurl = 'http://localhost:5173'  # Replace with your URL\n\nconsole_logs = []\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page(viewport={'width': 1920, 'height': 1080})\n\n    # Set up console log capture\n    def handle_console_message(msg):\n        console_logs.append(f\"[{msg.type}] {msg.text}\")\n        print(f\"Console: [{msg.type}] {msg.text}\")\n\n    page.on(\"console\", handle_console_message)\n\n    # Navigate to page\n    page.goto(url)\n    page.wait_for_load_state('networkidle')\n\n    # Interact with the page (triggers console logs)\n    page.click('text=Dashboard')\n    page.wait_for_timeout(1000)\n\n    browser.close()\n\n# Save console logs to file\nwith open('/mnt/user-data/outputs/console.log', 'w') as f:\n    f.write('\\n'.join(console_logs))\n\nprint(f\"\\nCaptured {len(console_logs)} console messages\")\nprint(f\"Logs saved to: /mnt/user-data/outputs/console.log\")"
  },
  {
    "path": "webapp-testing/examples/element_discovery.py",
    "content": "from playwright.sync_api import sync_playwright\n\n# Example: Discovering buttons and other elements on a page\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page()\n\n    # Navigate to page and wait for it to fully load\n    page.goto('http://localhost:5173')\n    page.wait_for_load_state('networkidle')\n\n    # Discover all buttons on the page\n    buttons = page.locator('button').all()\n    print(f\"Found {len(buttons)} buttons:\")\n    for i, button in enumerate(buttons):\n        text = button.inner_text() if button.is_visible() else \"[hidden]\"\n        print(f\"  [{i}] {text}\")\n\n    # Discover links\n    links = page.locator('a[href]').all()\n    print(f\"\\nFound {len(links)} links:\")\n    for link in links[:5]:  # Show first 5\n        text = link.inner_text().strip()\n        href = link.get_attribute('href')\n        print(f\"  - {text} -> {href}\")\n\n    # Discover input fields\n    inputs = page.locator('input, textarea, select').all()\n    print(f\"\\nFound {len(inputs)} input fields:\")\n    for input_elem in inputs:\n        name = input_elem.get_attribute('name') or input_elem.get_attribute('id') or \"[unnamed]\"\n        input_type = input_elem.get_attribute('type') or 'text'\n        print(f\"  - {name} ({input_type})\")\n\n    # Take screenshot for visual reference\n    page.screenshot(path='/tmp/page_discovery.png', full_page=True)\n    print(\"\\nScreenshot saved to /tmp/page_discovery.png\")\n\n    browser.close()"
  },
  {
    "path": "webapp-testing/examples/static_html_automation.py",
    "content": "from playwright.sync_api import sync_playwright\nimport os\n\n# Example: Automating interaction with static HTML files using file:// URLs\n\nhtml_file_path = os.path.abspath('path/to/your/file.html')\nfile_url = f'file://{html_file_path}'\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page(viewport={'width': 1920, 'height': 1080})\n\n    # Navigate to local HTML file\n    page.goto(file_url)\n\n    # Take screenshot\n    page.screenshot(path='/mnt/user-data/outputs/static_page.png', full_page=True)\n\n    # Interact with elements\n    page.click('text=Click Me')\n    page.fill('#name', 'John Doe')\n    page.fill('#email', 'john@example.com')\n\n    # Submit form\n    page.click('button[type=\"submit\"]')\n    page.wait_for_timeout(500)\n\n    # Take final screenshot\n    page.screenshot(path='/mnt/user-data/outputs/after_submit.png', full_page=True)\n\n    browser.close()\n\nprint(\"Static HTML automation completed!\")"
  },
  {
    "path": "webapp-testing/scripts/with_server.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nStart one or more servers, wait for them to be ready, run a command, then clean up.\n\nUsage:\n    # Single server\n    python scripts/with_server.py --server \"npm run dev\" --port 5173 -- python automation.py\n    python scripts/with_server.py --server \"npm start\" --port 3000 -- python test.py\n\n    # Multiple servers\n    python scripts/with_server.py \\\n      --server \"cd backend && python server.py\" --port 3000 \\\n      --server \"cd frontend && npm run dev\" --port 5173 \\\n      -- python test.py\n\"\"\"\n\nimport subprocess\nimport socket\nimport time\nimport sys\nimport argparse\n\ndef is_server_ready(port, timeout=30):\n    \"\"\"Wait for server to be ready by polling the port.\"\"\"\n    start_time = time.time()\n    while time.time() - start_time < timeout:\n        try:\n            with socket.create_connection(('localhost', port), timeout=1):\n                return True\n        except (socket.error, ConnectionRefusedError):\n            time.sleep(0.5)\n    return False\n\n\ndef main():\n    parser = argparse.ArgumentParser(description='Run command with one or more servers')\n    parser.add_argument('--server', action='append', dest='servers', required=True, help='Server command (can be repeated)')\n    parser.add_argument('--port', action='append', dest='ports', type=int, required=True, help='Port for each server (must match --server count)')\n    parser.add_argument('--timeout', type=int, default=30, help='Timeout in seconds per server (default: 30)')\n    parser.add_argument('command', nargs=argparse.REMAINDER, help='Command to run after server(s) ready')\n\n    args = parser.parse_args()\n\n    # Remove the '--' separator if present\n    if args.command and args.command[0] == '--':\n        args.command = args.command[1:]\n\n    if not args.command:\n        print(\"Error: No command specified to run\")\n        sys.exit(1)\n\n    # Parse server configurations\n    if len(args.servers) != len(args.ports):\n        print(\"Error: Number of --server and --port arguments must match\")\n        sys.exit(1)\n\n    servers = []\n    for cmd, port in zip(args.servers, args.ports):\n        servers.append({'cmd': cmd, 'port': port})\n\n    server_processes = []\n\n    try:\n        # Start all servers\n        for i, server in enumerate(servers):\n            print(f\"Starting server {i+1}/{len(servers)}: {server['cmd']}\")\n\n            # Use shell=True to support commands with cd and &&\n            process = subprocess.Popen(\n                server['cmd'],\n                shell=True,\n                stdout=subprocess.PIPE,\n                stderr=subprocess.PIPE\n            )\n            server_processes.append(process)\n\n            # Wait for this server to be ready\n            print(f\"Waiting for server on port {server['port']}...\")\n            if not is_server_ready(server['port'], timeout=args.timeout):\n                raise RuntimeError(f\"Server failed to start on port {server['port']} within {args.timeout}s\")\n\n            print(f\"Server ready on port {server['port']}\")\n\n        print(f\"\\nAll {len(servers)} server(s) ready\")\n\n        # Run the command\n        print(f\"Running: {' '.join(args.command)}\\n\")\n        result = subprocess.run(args.command)\n        sys.exit(result.returncode)\n\n    finally:\n        # Clean up all servers\n        print(f\"\\nStopping {len(server_processes)} server(s)...\")\n        for i, process in enumerate(server_processes):\n            try:\n                process.terminate()\n                process.wait(timeout=5)\n            except subprocess.TimeoutExpired:\n                process.kill()\n                process.wait()\n            print(f\"Server {i+1} stopped\")\n        print(\"All servers stopped\")\n\n\nif __name__ == '__main__':\n    main()"
  }
]